public void typeKey( double sec, final int charCode, final int keyCode, final boolean alt, final boolean ctrl, final boolean shift, final int delay, final boolean async) { if (!isSecure(sec)) return; // called by doh.robot._keyPress // see it for details AccessController.doPrivileged( new PrivilegedAction() { public Object run() { try { log("> typeKey Robot " + charCode + ", " + keyCode + ", " + async); KeyPressThread thread = new KeyPressThread( charCode, keyCode, alt, ctrl, shift, delay, async ? null : previousThread); previousThread = async ? previousThread : thread; thread.start(); log("< typeKey Robot"); } catch (Exception e) { log("Error calling typeKey"); e.printStackTrace(); } return null; } }); }
public void moveMouse(double sec, final int x1, final int y1, final int d, final int duration) { // called by doh.robot.mouseMove // see it for details // a nice name like "mouseMove" is reserved in Java if (!isSecure(sec)) return; AccessController.doPrivileged( new PrivilegedAction() { public Object run() { int x = x1 + docScreenX; int y = y1 + docScreenY; if (x > docScreenXMax || y > docScreenYMax) { // TODO: try to scroll view log("Request to mouseMove denied"); return null; } int delay = d; log("> mouseMove Robot " + x + ", " + y); MouseMoveThread thread = new MouseMoveThread(x, y, delay, duration, previousThread); previousThread = thread; thread.start(); log("< mouseMove Robot"); return null; } }); }
/** * Gets most recent focus owner component associated with the given window. It does that without * calling Window.getMostRecentFocusOwner since it provides its own logic contradicting with * setDefautlFocus. Instead, it calls KeyboardFocusManager directly. */ private Component getMostRecentFocusOwnerForWindow(Window w) { Method meth = AccessController.doPrivileged( new PrivilegedAction<Method>() { @Override public Method run() { Method meth = null; try { meth = KeyboardFocusManager.class.getDeclaredMethod( "getMostRecentFocusOwner", new Class<?>[] {Window.class}); meth.setAccessible(true); } catch (Exception e) { // Must never happen e.printStackTrace(); } return meth; } }); if (meth != null) { // Meth refers static method try { return (Component) meth.invoke(null, new Object[] {w}); } catch (Exception e) { // Must never happen e.printStackTrace(); } } // Will get here if exception was thrown or meth is null return w.getMostRecentFocusOwner(); }
/* * Creates a thread to run the applet. This method is called * each time an applet is loaded and reloaded. */ synchronized void createAppletThread() { // Create a thread group for the applet, and start a new // thread to load the applet. String nm = "applet-" + getCode(); loader = getClassLoader(getCodeBase(), getClassLoaderCacheKey()); loader.grab(); // Keep this puppy around! // 4668479: Option to turn off codebase lookup in AppletClassLoader // during resource requests. [stanley.ho] String param = getParameter("codebase_lookup"); if (param != null && param.equals("false")) loader.setCodebaseLookup(false); else loader.setCodebaseLookup(true); ThreadGroup appletGroup = loader.getThreadGroup(); handler = new Thread(appletGroup, this, "thread " + nm, 0, false); // set the context class loader for this thread AccessController.doPrivileged( new PrivilegedAction<Object>() { @Override public Object run() { handler.setContextClassLoader(loader); return null; } }); handler.start(); }
public void componentShown(ComponentEvent evt) { // sets the security manager to fix a bug in liveconnect in Safari on Mac if (key != -1) { return; } window = (JSObject) JSObject.getWindow(applet()); AccessController.doPrivileged( new PrivilegedAction() { public Object run() { log("> init Robot"); try { SecurityManager oldsecurity = System.getSecurityManager(); boolean isOpera = false; try { isOpera = (System.getProperty("browser").equals("Opera.plugin")); } catch (Exception e) { } try { securitymanager = oldsecurity; securitymanager.checkTopLevelWindow(null); // xdomain if (charMap == null) { if (!confirm( "DOH has detected that the current Web page is attempting to access DOH, but belongs to a different domain than the one you agreed to let DOH automate. If you did not intend to start a new DOH test by visiting this Web page, press Cancel now and leave the Web page. Otherwise, press OK to trust this domain to automate DOH tests.")) { stop(); return null; } } log("Found old security manager"); } catch (Exception e) { e.printStackTrace(); log("Making new security manager"); securitymanager = new RobotSecurityManager(isOpera, oldsecurity); securitymanager.checkTopLevelWindow(null); System.setSecurityManager(securitymanager); } // instantiate the Robot robot = new Robot(); } catch (Exception e) { log("Error calling _init_: " + e.getMessage()); key = -2; e.printStackTrace(); } log("< init Robot"); return null; } }); if (key == -2) { // applet not trusted // start the test without it window.eval("doh.robot._appletDead=true;doh.run();"); } else { // now that the applet has really started, let doh know it's ok to use it log("_initRobot"); dohrobot = (JSObject) window.eval("doh.robot"); dohrobot.call("_initRobot", new Object[] {applet()}); } }
public void log(final String s) { AccessController.doPrivileged( new PrivilegedAction() { public Object run() { System.out.println((new Date()).toString() + ": " + s); return null; } }); }
private void alert(final String s) { AccessController.doPrivileged( new PrivilegedAction() { public Object run() { window.eval("top.alert(\"" + s + "\");"); return null; } }); }
private boolean confirm(final String s) { return ((Boolean) AccessController.doPrivileged( new PrivilegedAction() { public Object run() { return ((Boolean) window.eval("top.confirm(\"" + s + "\");")); } })) .booleanValue(); }
public void wheelMouse(double sec, final int amount, final int delay, final int duration) { // called by doh.robot.mouseWheel // see it for details if (!isSecure(sec)) return; AccessController.doPrivileged( new PrivilegedAction() { public Object run() { MouseWheelThread thread = new MouseWheelThread(amount, delay, duration, previousThread); previousThread = thread; thread.start(); return null; } }); }
/** Handles mouse dragged event */ public void mouseDragged(MouseEvent ev) { Window w = (Window) ev.getSource(); if (isMovingWindow) { Point windowPt; try { windowPt = (Point) AccessController.doPrivileged(getLocationAction); windowPt.x = windowPt.x - dragOffsetX; windowPt.y = windowPt.y - dragOffsetY; w.setLocation(windowPt); windowMoved = true; } catch (PrivilegedActionException e) { } } }
public void downKey(double sec, final int charCode, final int keyCode, final int delay) { // called by doh.robot.keyUp // see it for details // a nice name like "keyDown" is reserved in Java if (!isSecure(sec)) return; AccessController.doPrivileged( new PrivilegedAction() { public Object run() { log("> downKey Robot " + charCode + ", " + keyCode); KeyDownThread thread = new KeyDownThread(charCode, keyCode, delay, previousThread); previousThread = thread; thread.start(); log("< downKey Robot"); return null; } }); }
// java.awt.Applet methods public void stop() { window = null; // only secure code run once if (key != -2) { // prevent further execution of secure functions key = -2; // Java calls this when you close the window. // It plays nice and restores the old security manager. AccessController.doPrivileged( new PrivilegedAction() { public Object run() { log("Stop"); securitymanager.checkTopLevelWindow(null); log("Security manager reset"); return null; } }); } }
/** Get a class loader. Create in a restricted context */ synchronized AppletClassLoader getClassLoader(final URL codebase, final String key) { AppletClassLoader c = classloaders.get(key); if (c == null) { AccessControlContext acc = getAccessControlContext(codebase); c = AccessController.doPrivileged( new PrivilegedAction<AppletClassLoader>() { @Override public AppletClassLoader run() { AppletClassLoader ac = createClassLoader(codebase); /* Should the creation of the classloader be * within the class synchronized block? Since * this class is used by the plugin, take care * to avoid deadlocks, or specialize * AppletPanel within the plugin. It may take * an arbitrary amount of time to create a * class loader (involving getting Jar files * etc.) and may block unrelated applets from * finishing createAppletThread (due to the * class synchronization). If * createAppletThread does not finish quickly, * the applet cannot process other messages, * particularly messages such as destroy * (which timeout when called from the browser). */ synchronized (getClass()) { AppletClassLoader res = classloaders.get(key); if (res == null) { classloaders.put(key, ac); return ac; } else { return res; } } } }, acc); } return c; }
public void releaseMouse( double sec, final boolean left, final boolean middle, final boolean right, final int delay) { if (!isSecure(sec)) return; // called by doh.robot.mouseRelease // see it for details // a nice name like "mouseRelease" is reserved in Java AccessController.doPrivileged( new PrivilegedAction() { public Object run() { log("> mouseRelease Robot " + left + ", " + middle + ", " + right); MouseReleaseThread thread = new MouseReleaseThread( (left ? InputEvent.BUTTON1_MASK : 0) + (middle ? InputEvent.BUTTON2_MASK : 0) + (right ? InputEvent.BUTTON3_MASK : 0), delay, previousThread); previousThread = thread; thread.start(); log("< mouseRelease Robot"); return null; } }); }
/** * get the context for the AppletClassLoader we are creating. the context is granted permission to * create the class loader, connnect to the codebase, and whatever else the policy grants to all * codebases. */ private AccessControlContext getAccessControlContext(final URL codebase) { PermissionCollection perms = AccessController.doPrivileged( new PrivilegedAction<PermissionCollection>() { @Override public PermissionCollection run() { Policy p = java.security.Policy.getPolicy(); if (p != null) { return p.getPermissions( new CodeSource(null, (java.security.cert.Certificate[]) null)); } else { return null; } } }); if (perms == null) perms = new Permissions(); // XXX: this is needed to be able to create the classloader itself! perms.add(SecurityConstants.CREATE_CLASSLOADER_PERMISSION); Permission p; java.net.URLConnection urlConnection = null; try { urlConnection = codebase.openConnection(); p = urlConnection.getPermission(); } catch (java.io.IOException ioe) { p = null; } if (p != null) perms.add(p); if (p instanceof FilePermission) { String path = p.getName(); int endIndex = path.lastIndexOf(File.separatorChar); if (endIndex != -1) { path = path.substring(0, endIndex + 1); if (path.endsWith(File.separator)) { path += "-"; } perms.add(new FilePermission(path, SecurityConstants.FILE_READ_ACTION)); } } else { URL locUrl = codebase; if (urlConnection instanceof JarURLConnection) { locUrl = ((JarURLConnection) urlConnection).getJarFileURL(); } String host = locUrl.getHost(); if (host != null && (host.length() > 0)) perms.add(new SocketPermission(host, SecurityConstants.SOCKET_CONNECT_ACCEPT_ACTION)); } ProtectionDomain domain = new ProtectionDomain( new CodeSource(codebase, (java.security.cert.Certificate[]) null), perms); AccessControlContext acc = new AccessControlContext(new ProtectionDomain[] {domain}); return acc; }
public void _initKeyboard(double sec) { log("> initKeyboard"); // javascript entry point to discover the keyboard if (!isSecure(sec)) return; if (charMap != null) { dohrobot.call("_onKeyboard", new Object[] {}); return; } AccessController.doPrivileged( new PrivilegedAction() { public Object run() { charMap = new HashMap(); KeyEvent event = new KeyEvent(applet(), 0, 0, 0, KeyEvent.VK_SPACE, ' '); charMap.put(new Integer(32), event); try { // a-zA-Z0-9 + 29 others vkKeys = new Vector(); for (char i = 'a'; i <= 'z'; i++) { vkKeys.add( new Integer( KeyEvent.class .getField("VK_" + Character.toUpperCase((char) i)) .getInt(null))); } for (char i = '0'; i <= '9'; i++) { vkKeys.add( new Integer( KeyEvent.class .getField("VK_" + Character.toUpperCase((char) i)) .getInt(null))); } int[] mykeys = new int[] { KeyEvent.VK_COMMA, KeyEvent.VK_MINUS, KeyEvent.VK_PERIOD, KeyEvent.VK_SLASH, KeyEvent.VK_SEMICOLON, KeyEvent.VK_LEFT_PARENTHESIS, KeyEvent.VK_NUMBER_SIGN, KeyEvent.VK_PLUS, KeyEvent.VK_RIGHT_PARENTHESIS, KeyEvent.VK_UNDERSCORE, KeyEvent.VK_EXCLAMATION_MARK, KeyEvent.VK_DOLLAR, KeyEvent.VK_CIRCUMFLEX, KeyEvent.VK_AMPERSAND, KeyEvent.VK_ASTERISK, KeyEvent.VK_QUOTEDBL, KeyEvent.VK_LESS, KeyEvent.VK_GREATER, KeyEvent.VK_BRACELEFT, KeyEvent.VK_BRACERIGHT, KeyEvent.VK_COLON, KeyEvent.VK_BACK_QUOTE, KeyEvent.VK_QUOTE, KeyEvent.VK_OPEN_BRACKET, KeyEvent.VK_BACK_SLASH, KeyEvent.VK_CLOSE_BRACKET, KeyEvent.VK_EQUALS }; for (int i = 0; i < mykeys.length; i++) { vkKeys.add(new Integer(mykeys[i])); } } catch (Exception e) { e.printStackTrace(); } Thread thread = new Thread() { public void run() { robot.setAutoDelay(0); log("< initKeyboard"); pressNext(); } }; thread.start(); return null; } }); }
/** Determine JDK level of an applet. */ private void findAppletJDKLevel(Applet applet) { // To determine the JDK level of an applet, the // most reliable way is to check the major version // of the applet class file. // synchronized on applet class object, so calling from // different instances of the same applet will be // serialized. Class<?> appletClass = applet.getClass(); synchronized (appletClass) { // Determine if the JDK level of an applet has been // checked before. Boolean jdk11Target = loader.isJDK11Target(appletClass); Boolean jdk12Target = loader.isJDK12Target(appletClass); // if applet JDK level has been checked before, retrieve // value and return. if (jdk11Target != null || jdk12Target != null) { jdk11Applet = (jdk11Target == null) ? false : jdk11Target.booleanValue(); jdk12Applet = (jdk12Target == null) ? false : jdk12Target.booleanValue(); return; } String name = appletClass.getName(); // first convert any '.' to '/' name = name.replace('.', '/'); // append .class final String resourceName = name + ".class"; byte[] classHeader = new byte[8]; try (InputStream is = AccessController.doPrivileged( (PrivilegedAction<InputStream>) () -> loader.getResourceAsStream(resourceName))) { // Read the first 8 bytes of the class file int byteRead = is.read(classHeader, 0, 8); // return if the header is not read in entirely // for some reasons. if (byteRead != 8) return; } catch (IOException e) { return; } // Check major version in class file header int major_version = readShort(classHeader, 6); // Major version in class file is as follows: // 45 - JDK 1.1 // 46 - JDK 1.2 // 47 - JDK 1.3 // 48 - JDK 1.4 // 49 - JDK 1.5 if (major_version < 46) jdk11Applet = true; else if (major_version == 46) jdk12Applet = true; // Store applet JDK level in AppContext for later lookup, // e.g. page switch. loader.setJDK11Target(appletClass, jdk11Applet); loader.setJDK12Target(appletClass, jdk12Applet); } }
private void _typeKey( final int cCode, final int kCode, final boolean a, final boolean c, final boolean s) { AccessController.doPrivileged( new PrivilegedAction() { public Object run() { int charCode = cCode; int keyCode = kCode; boolean alt = a; boolean ctrl = c; boolean shift = s; boolean altgraph = false; log("> _typeKey Robot " + charCode + ", " + keyCode); try { int keyboardCode = getVKCode(charCode, keyCode); if (charCode >= 32) { // if it is printable, then it lives in our hashmap KeyEvent event = (KeyEvent) charMap.get(new Integer(charCode)); // see if we need to press shift to generate this // character if (!shift) { shift = event.isShiftDown(); } altgraph = event.isAltGraphDown(); keyboardCode = event.getKeyCode(); } // run through exemption list if (!isUnsafe(keyboardCode)) { if (shift) { log("Pressing shift"); robot.keyPress(KeyEvent.VK_SHIFT); } if (alt) { log("Pressing alt"); robot.keyPress(KeyEvent.VK_ALT); } if (altgraph) { log("Pressing altgraph"); robot.keyPress(KeyEvent.VK_ALT_GRAPH); } if (ctrl) { log("Pressing ctrl"); robot.keyPress(KeyEvent.VK_CONTROL); } if (keyboardCode != KeyEvent.VK_SHIFT && keyboardCode != KeyEvent.VK_ALT && keyboardCode != KeyEvent.VK_CONTROL) { try { robot.keyPress(keyboardCode); robot.keyRelease(keyboardCode); } catch (Exception e) { log("Error while actually typing a key"); e.printStackTrace(); } } if (ctrl) { robot.keyRelease(KeyEvent.VK_CONTROL); ctrl = false; } if (alt) { robot.keyRelease(KeyEvent.VK_ALT); alt = false; } if (altgraph) { robot.keyRelease(KeyEvent.VK_ALT_GRAPH); altgraph = false; } if (shift) { log("Releasing shift"); robot.keyRelease(KeyEvent.VK_SHIFT); shift = false; } } } catch (Exception e) { log("Error in _typeKey"); e.printStackTrace(); } log("< _typeKey Robot"); return null; } }); }
public void mouseDragged(MouseEvent ev) { Window w = (Window) ev.getSource(); Point pt = ev.getPoint(); if (isMovingWindow) { Point windowPt; try { windowPt = (Point) AccessController.doPrivileged(getLocationAction); windowPt.x = windowPt.x - dragOffsetX; windowPt.y = windowPt.y - dragOffsetY; w.setLocation(windowPt); } catch (PrivilegedActionException e) { } } else if (dragCursor != 0) { Rectangle r = w.getBounds(); Rectangle startBounds = new Rectangle(r); Dimension min = w.getMinimumSize(); switch (dragCursor) { case Cursor.E_RESIZE_CURSOR: adjust(r, min, 0, 0, pt.x + (dragWidth - dragOffsetX) - r.width, 0); break; case Cursor.S_RESIZE_CURSOR: adjust(r, min, 0, 0, 0, pt.y + (dragHeight - dragOffsetY) - r.height); break; case Cursor.N_RESIZE_CURSOR: adjust(r, min, 0, pt.y - dragOffsetY, 0, -(pt.y - dragOffsetY)); break; case Cursor.W_RESIZE_CURSOR: adjust(r, min, pt.x - dragOffsetX, 0, -(pt.x - dragOffsetX), 0); break; case Cursor.NE_RESIZE_CURSOR: adjust( r, min, 0, pt.y - dragOffsetY, pt.x + (dragWidth - dragOffsetX) - r.width, -(pt.y - dragOffsetY)); break; case Cursor.SE_RESIZE_CURSOR: adjust( r, min, 0, 0, pt.x + (dragWidth - dragOffsetX) - r.width, pt.y + (dragHeight - dragOffsetY) - r.height); break; case Cursor.NW_RESIZE_CURSOR: adjust( r, min, pt.x - dragOffsetX, pt.y - dragOffsetY, -(pt.x - dragOffsetX), -(pt.y - dragOffsetY)); break; case Cursor.SW_RESIZE_CURSOR: adjust( r, min, pt.x - dragOffsetX, 0, -(pt.x - dragOffsetX), pt.y + (dragHeight - dragOffsetY) - r.height); break; default: break; } if (!r.equals(startBounds)) { w.setBounds(r); // Defer repaint/validate on mouseReleased unless dynamic // layout is active. if (Toolkit.getDefaultToolkit().isDynamicLayoutActive()) { w.validate(); getRootPane().repaint(); } } } }
/** Does install of JRE */ public static void install() { // Hide the JNLP Clients installer window and show own Config.getInstallService().hideStatusWindow(); showInstallerWindow(); // Make sure the destination exists. String path = Config.getInstallService().getInstallPath(); if (Config.isWindowsInstall()) { String defaultLocation = "C:\\Program Files\\Java\\j2re" + Config.getJavaVersion() + "\\"; File defaultDir = new File(defaultLocation); if (!defaultDir.exists()) { defaultDir.mkdirs(); } if (defaultDir.exists() && defaultDir.canWrite()) { path = defaultLocation; // use default if you can } } File installDir = new File(path); if (!installDir.exists()) { installDir.mkdirs(); if (!installDir.exists()) { // The installFailed string is only for debugging. No localization needed installFailed("couldntCreateDirectory", null); return; } } // Show license if neccesary enableStep(STEP_LICENSE); if (!showLicensing()) { // The installFailed string is only for debugging. No localization needed installFailed("Licensing was not accepted", null); } ; // Make sure that the data JAR is downloaded enableStep(STEP_DOWNLOAD); if (!downloadInstallerComponent()) { // The installFailed string is only for debugging. No localization needed installFailed("Unable to download data component", null); } String nativeLibName = Config.getNativeLibName(); File installerFile = null; try { // Load native library into process if found if (nativeLibName != null && !Config.isSolarisInstall()) { System.loadLibrary(nativeLibName); } // Unpack installer enableStep(STEP_UNPACK); String installResource = Config.getInstallerResource(); Config.trace("Installer resource: " + installResource); installerFile = unpackInstaller(installResource); // To clean-up downloaded files Config.trace("Unpacked installer to: " + installerFile); if (installerFile == null) { // The installFailed string is only for debugging. No localization needed installFailed("Could not unpack installer components", null); return; } enableStep(STEP_INSTALL); setStepText(STEP_INSTALL, Config.getWindowStepWait(STEP_INSTALL)); boolean success = false; if (Config.isSolarisInstall()) { success = runSolarisInstaller(path, installerFile); } else { success = runWindowsInstaller(path, installerFile); } if (!success) { // The installFailed string is only for debugging. No localization needed installFailed("Could not run installer", null); return; } } catch (UnsatisfiedLinkError ule) { // The installFailed string is only for debugging. No localization needed installFailed("Unable to load library: " + nativeLibName, null); return; } finally { if (installerFile != null) { installerFile.delete(); } } setStepText(STEP_INSTALL, Config.getWindowStep(STEP_INSTALL)); enableStep(STEP_DONE); String execPath = path + Config.getJavaPath(); Config.trace(execPath); /** Remove installer JAR from cache */ removeInstallerComponent(); // If we're running anything after 1.0.1 or not on Windows, just call // finishedInstall. Otherwise, deny ExitVM permission so that we can // return here and do a reboot. We have to do this because we need to // call ExtensionInstallerService.finishedInstall(), which registers // that our extension (the JRE) is installed. Unfortunately pre-1.2 it // also does not understand that we are requesting a reboot, and calls // System.exit(). So for pre 1.2 we want to deny the permission to // exit the VM so we can return here and perform a reboot. boolean ispre12 = false; String version = Config.getJavaWSVersion(); // get first tuple String v = version.substring(version.indexOf('-') + 1); int i2 = v.indexOf('.'); int v1 = Integer.parseInt(v.substring(0, i2)); // get second tuple v = v.substring(i2 + 1); i2 = v.indexOf('.'); if (i2 == -1) i2 = v.indexOf('-'); if (i2 == -1) i2 = v.indexOf('['); if (i2 == -1) i2 = v.length(); int v2 = Integer.parseInt(v.substring(0, i2)); // are we pre 1.2? if (v1 < 1 || (v1 == 1 && v2 < 2)) ispre12 = true; if (Config.isWindowsInstall() && ispre12 && Config.isHopper()) { // deny ExitVM permission then call finishedInstall ProtectionDomain pd = (new Object()).getClass().getProtectionDomain(); CodeSource cs = pd.getCodeSource(); AllPermissionExceptExitVM perm = new AllPermissionExceptExitVM(); PermissionCollection newpc = perm.newPermissionCollection(); newpc.add(perm); // run finishedInstall within the new context which excluded // just the ExitVM permission ProtectionDomain newpd = new ProtectionDomain(cs, newpc); AccessControlContext newacc = new AccessControlContext(new ProtectionDomain[] {newpd}); final String fExecPath = execPath; try { AccessController.doPrivileged( new PrivilegedExceptionAction() { public Object run() throws SecurityException { finishedInstall(fExecPath); return null; } }, newacc); } catch (PrivilegedActionException pae) { // swallow the exception because we want ExitVM to fail silent } catch (SecurityException se) { // swallow the exception because we want ExitVM to fail silent } } else { // just call finished Install finishedInstall(execPath); } if (Config.isWindowsInstall() && WindowsInstaller.IsRebootNecessary()) { // reboot if (!WindowsInstaller.askUserForReboot()) System.exit(0); } else { System.exit(0); } }