diff options
Diffstat (limited to 'netx/net/sourceforge/jnlp/services/ServiceUtil.java')
-rw-r--r-- | netx/net/sourceforge/jnlp/services/ServiceUtil.java | 293 |
1 files changed, 293 insertions, 0 deletions
diff --git a/netx/net/sourceforge/jnlp/services/ServiceUtil.java b/netx/net/sourceforge/jnlp/services/ServiceUtil.java new file mode 100644 index 0000000..b6f7682 --- /dev/null +++ b/netx/net/sourceforge/jnlp/services/ServiceUtil.java @@ -0,0 +1,293 @@ +// Copyright (C) 2001-2003 Jon A. Maxwell (JAM) +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library 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 +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + +package net.sourceforge.jnlp.services; + +import java.lang.reflect.InvocationHandler; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.security.AccessController; +import java.security.PrivilegedAction; +import java.security.PrivilegedActionException; +import java.security.PrivilegedExceptionAction; + +import javax.jnlp.BasicService; +import javax.jnlp.ClipboardService; +import javax.jnlp.DownloadService; +import javax.jnlp.ExtensionInstallerService; +import javax.jnlp.FileOpenService; +import javax.jnlp.FileSaveService; +import javax.jnlp.PersistenceService; +import javax.jnlp.PrintService; +import javax.jnlp.ServiceManager; +import javax.jnlp.SingleInstanceService; +import javax.jnlp.UnavailableServiceException; + +import net.sourceforge.jnlp.JNLPFile; +import net.sourceforge.jnlp.runtime.ApplicationInstance; +import net.sourceforge.jnlp.runtime.JNLPRuntime; +import net.sourceforge.jnlp.security.SecurityWarningDialog; + +/** + * Provides static methods to interact useful for using the JNLP + * services.<p> + * + * @author <a href="mailto:[email protected]">Jon A. Maxwell (JAM)</a> - initial author + * @author <a href="mailto:[email protected]">Joshua Sumali</a> + * @version $Revision: 1.8 $ + */ +public class ServiceUtil { + + private static String R(String key) { + return JNLPRuntime.getMessage(key); + } + + /** + * Returns the BasicService reference, or null if the service is + * unavailable. + */ + public static BasicService getBasicService() { + return (BasicService) getService("javax.jnlp.BasicService"); + } + + /** + * Returns the ClipboardService reference, or null if the service is + * unavailable. + */ + public static ClipboardService getClipboardService() { + return (ClipboardService) getService("javax.jnlp.ClipboardService"); + } + + /** + * Returns the DownloadService reference, or null if the service is + * unavailable. + */ + public static DownloadService getDownloadService() { + return (DownloadService) getService("javax.jnlp.DownloadService"); + } + + /** + * Returns the ExtensionInstallerService reference, or null if the service is + * unavailable. + */ + public static ExtensionInstallerService getExtensionInstallerService() { + return (ExtensionInstallerService) getService("javax.jnlp.ExtensionInstallerService"); + } + + /** + * Returns the FileOpenService reference, or null if the service is + * unavailable. + */ + public static FileOpenService getFileOpenService() { + return (FileOpenService) getService("javax.jnlp.FileOpenService"); + } + + /** + * Returns the FileSaveService reference, or null if the service is + * unavailable. + */ + public static FileSaveService getFileSaveService() { + return (FileSaveService) getService("javax.jnlp.FileSaveService"); + } + + /** + * Returns the PersistenceService reference, or null if the service is + * unavailable. + */ + public static PersistenceService getPersistenceService() { + return (PersistenceService) getService("javax.jnlp.PersistenceService"); + } + + /** + * Returns the PrintService reference, or null if the service is + * unavailable. + */ + public static PrintService getPrintService() { + return (PrintService) getService("javax.jnlp.PrintService"); + } + + /** + * Returns the SingleInstanceService reference, or null if the service is + * unavailable. + */ + public static SingleInstanceService getSingleInstanceService() { + return (SingleInstanceService) getService("javax.jnlp.SingleInstanceService"); + } + + /** + * Checks that this application (represented by the jnlp) isnt already running + * @param jnlpFile the {@link JNLPFile} that specifies the application + * + * @throws InstanceExistsException if an instance of this application already exists + */ + public static void checkExistingSingleInstance(JNLPFile jnlpFile) { + ExtendedSingleInstanceService esis = (ExtendedSingleInstanceService) getSingleInstanceService(); + esis.checkSingleInstanceRunning(jnlpFile); + } + + /** + * Returns the service, or null instead of an UnavailableServiceException + */ + private static Object getService(String name) { + try { + return ServiceManager.lookup(name); + } + catch (UnavailableServiceException ex) { + return null; + } + } + + /** + * Creates a Proxy object implementing the specified interface + * when makes all calls in the security context of the system + * classes (ie, AllPermissions). This means that the services + * must be more than extremely careful in the operations they + * perform. + */ + static Object createPrivilegedProxy(Class iface, final Object receiver) { + return java.lang.reflect.Proxy.newProxyInstance(XServiceManagerStub.class.getClassLoader(), + new Class[] { iface }, + new PrivilegedHandler(receiver)); + } + + /** + * calls the object's method using privileged access + */ + private static class PrivilegedHandler implements InvocationHandler { + private final Object receiver; + + PrivilegedHandler(Object receiver) { + this.receiver = receiver; + } + + public Object invoke(Object proxy, final Method method, final Object[] args) throws Throwable { + if (JNLPRuntime.isDebug()) { + System.err.println("call privileged method: "+method.getName()); + if (args != null) + for (int i=0; i < args.length; i++) + System.err.println(" arg: "+args[i]); + } + + PrivilegedExceptionAction invoker = new PrivilegedExceptionAction() { + public Object run() throws Exception { + return method.invoke(receiver, args); + } + }; + + try { + Object result = AccessController.doPrivileged(invoker); + + if (JNLPRuntime.isDebug()) + System.err.println(" result: "+result); + + return result; + } catch (PrivilegedActionException e) { + // Any exceptions thrown by the actual methods are wrapped by a + // InvocationTargetException, which is further wrapped by the + // PrivilegedActionException. Lets unwrap them to make the + // proxy transparent to the callers + if (e.getCause() instanceof InvocationTargetException) { + throw e.getCause().getCause(); + } else { + throw e.getCause(); + } + } + + } + }; + + /** + * Returns whether the app requesting a service is signed. If the app is + * unsigned, the user is prompted with a dialog asking if the action + * should be allowed. + * @param type the type of access being requested + * @param extras extra Strings (usually) that are passed to the dialog for + * message formatting. + * @return true if the access was granted, false otherwise. + */ + public static boolean checkAccess(SecurityWarningDialog.AccessType type, + Object... extras) { + return checkAccess(null, type, extras); + } + + /** + * Returns whether the app requesting a service has the right permissions. + * If it doesn't, user is prompted for permissions. + * + * @param app the application which is requesting the check. If null, the current + * application is used. + * @param type the type of access being requested + * @param extras extra Strings (usually) that are passed to the dialog for + * message formatting. + * @return true if the access was granted, false otherwise. + */ + public static boolean checkAccess(ApplicationInstance app, + SecurityWarningDialog.AccessType type, + Object... extras) { + + if (app == null) + app = JNLPRuntime.getApplication(); + + boolean codeTrusted = true; + + StackTraceElement[] stack = Thread.currentThread().getStackTrace(); + + for (int i=0; i < stack.length; i++) { + + Class c = null; + + try { + c = Class.forName(stack[i].getClassName()); + } catch (Exception e1) { + try { + c = Class.forName(stack[i].getClassName(), false, app.getClassLoader()); + } catch (Exception e2) { + System.err.println(e2.getMessage()); + } + } + + // Everything up to the desired class/method must be trusted + if (c == null || // class not found + ( c.getProtectionDomain().getCodeSource() != null && // class is not in bootclasspath + c.getProtectionDomain().getCodeSource().getCodeSigners() == null) // class is trusted + ) { + codeTrusted = false; + } + } + + if (!codeTrusted) { + final SecurityWarningDialog.AccessType tmpType = type; + final Object[] tmpExtras = extras; + final ApplicationInstance tmpApp = app; + + //We need to do this to allow proper icon loading for unsigned + //applets, otherwise permissions won't be granted to load icons + //from resources.jar. + Boolean b = AccessController.doPrivileged(new PrivilegedAction<Boolean>() { + public Boolean run() { + boolean b = SecurityWarningDialog.showAccessWarningDialog(tmpType, + tmpApp.getJNLPFile(), tmpExtras); + return new Boolean(b); + } + }); + + return b.booleanValue(); + } + + return true; //allow + } +} |