/* * RHQ Management Platform * Copyright (C) 2005-2011 Red Hat, Inc. * All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation version 2 of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ package org.rhq.bindings; import static org.testng.Assert.assertNotNull; import static org.testng.Assert.assertTrue; import java.io.File; import java.io.IOException; import java.io.PrintWriter; import java.util.Collections; import javax.script.ScriptContext; import javax.script.ScriptEngine; import javax.script.ScriptException; import org.testng.annotations.Test; import org.rhq.bindings.util.PackageFinder; /** * * * @author Lukas Krejci */ public class ScriptEngineTest extends ScriptedTestBase { private static StandardBindings EMPTY_BINDINGS = new StandardBindings(new PrintWriter(System.out), new FakeRhqFacade()); @Test public void testFactory_javascript() throws ScriptException, IOException { ScriptEngine engine = getScriptEngine(); assertNotNull(engine); } @Test public void testFactory_python() throws ScriptException, IOException { ScriptEngine engine = getScriptEngine(); assertNotNull(engine); } @Test public void testSandbox_javascript() throws ScriptException, IOException { ScriptEngine sandbox = getSecuredScriptEngine(); try { sandbox.eval("java.lang.System.exit(1);"); } catch (Exception e) { assertSecurityExceptionPresent(e); } try { //try hard to get to the System.exit() sandbox.eval( "cls = java.lang.Class.forName('java.lang.System');" + "params = java.lang.reflect.Array.newInstance(java.lang.Object, 1);" + "params[0] = java.lang.Integer.valueOf('1');" + "st = new java.beans.Statement(cls, 'exit', params);" + "st.execute()"); } catch (Exception e) { assertSecurityExceptionPresent(e); } } @Test public void testSandbox_python() throws Exception { ScriptEngine sandbox = getSecuredScriptEngine(); try { sandbox.eval("import java.lang as foo\nfoo.System.exit(1)"); } catch (Exception e) { assertSecurityExceptionPresent(e); } try { //try hard to get to the System.exit() sandbox.eval( "import java.lang as l\n" + "import java.lang.reflect as r\n" + "import java.beans as b\n" + "cls = l.Class.forName('java.lang.System')\n" + "params = r.Array.newInstance(l.Class.forName('java.lang.Object'), 1)\n" + "params[0] = l.Integer.valueOf('1')\n" + "st = b.Statement(cls, 'exit', params)\n" + "st.execute()"); } catch (Exception e) { assertSecurityExceptionPresent(e); } } @Test public void testStandardBindings_javascript() throws ScriptException, IOException { ScriptEngine scriptEngine = getScriptEngine(); for(String var : EMPTY_BINDINGS.keySet()) { boolean hasVar = scriptEngine.getBindings(ScriptContext.ENGINE_SCOPE).containsKey(var); assertTrue(hasVar, "The variable '" + var + "' is not present in the script context but should be."); } } @Test public void testStandardBindings_python() throws Exception { ScriptEngine scriptEngine = getScriptEngine(); for(String var : EMPTY_BINDINGS.keySet()) { boolean hasVar = scriptEngine.getBindings(ScriptContext.ENGINE_SCOPE).containsKey(var); assertTrue(hasVar, "The variable '" + var + "' is not present in the script context but should be."); } } private ScriptEngine getScriptEngine() throws ScriptException, IOException { return getScriptEngine(new PackageFinder(Collections.<File> emptyList()), EMPTY_BINDINGS); } private ScriptEngine getSecuredScriptEngine() throws ScriptException, IOException { return getSecuredScriptEngine(new PackageFinder(Collections.<File> emptyList()), EMPTY_BINDINGS, new StandardScriptPermissions()); } private void assertSecurityExceptionPresent(Throwable t) { boolean ok = false; while (t != null) { if (t instanceof SecurityException) { ok = true; break; } else if ((t instanceof ScriptException) && (t.getMessage().contains("java.security.AccessControlException") || t.getMessage().contains("java.lang.SecurityException"))) { ok = true; break; } t = t.getCause(); } assertTrue(ok, "Didn't find a SecurityException, which should have occured."); } }