mirror of
https://github.com/moparisthebest/MoparScape
synced 2024-08-13 16:23:46 -04:00
SecurityManager is now gold, hopefully. Interfaces are fully javadoc'd, should be ready to release finally.
This commit is contained in:
parent
a964437d1a
commit
7436e5405e
@ -27,6 +27,7 @@ import java.net.InetAddress;
|
||||
import java.net.Socket;
|
||||
import java.net.URL;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class client extends RSApplet {
|
||||
|
||||
@ -92,7 +93,7 @@ public class client extends RSApplet {
|
||||
return serverPort;
|
||||
}
|
||||
|
||||
public HashMap<String, String> getParams() {
|
||||
public Map<String, String> getParams() {
|
||||
HashMap<String, String> ret = new HashMap<String, String>();
|
||||
// set params
|
||||
ret.put("getCodeBase", "http://localhost");
|
||||
|
@ -10,6 +10,7 @@ import java.awt.image.PixelGrabber;
|
||||
import java.net.Socket;
|
||||
import java.util.GregorianCalendar;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class client extends Applet_Sub1 implements ClientInterface {
|
||||
|
||||
@ -69,7 +70,7 @@ public class client extends Applet_Sub1 implements ClientInterface {
|
||||
return serverPort;
|
||||
}
|
||||
|
||||
public HashMap<String, String> getParams() {
|
||||
public Map<String, String> getParams() {
|
||||
HashMap<String, String> ret = new HashMap<String, String>();
|
||||
// set params
|
||||
ret.put("getCodeBase", "http://localhost");
|
||||
|
@ -21,44 +21,156 @@
|
||||
package org.moparscape.iface;
|
||||
|
||||
/**
|
||||
* This interface must be implemented for moparscape to load this applet as a client.
|
||||
* For two different working examples, check the 317 and 508 clients implementing this interface.
|
||||
* <p/>
|
||||
* The only methods that *MUST* be implemented correctly are the ones that say so, namely setServer, setPort, getPort,
|
||||
* setCacheDir, setKeyListener, and getParams.
|
||||
*
|
||||
* @author mopar
|
||||
*/
|
||||
public interface ClientInterface {
|
||||
|
||||
public static final long serialVersionUID = 42L;
|
||||
public static final long serialVersionUID = 43L;
|
||||
|
||||
/**
|
||||
* Sets the server address the user wishes to connect to.
|
||||
* <p/>
|
||||
* This *MUST* be implemented correctly.
|
||||
*
|
||||
* @param server The address of the private server the client should connect to next time 'login' is pressed.
|
||||
*/
|
||||
public void setServer(String server);
|
||||
|
||||
/**
|
||||
* Sets the port of the private server the user wishes to connect to.
|
||||
* <p/>
|
||||
* This *MUST* be implemented correctly.
|
||||
*
|
||||
* @param port The port number to be used when connecting to the server.
|
||||
*/
|
||||
public void setPort(int port);
|
||||
|
||||
public void setCacheDir(String cacheDir);
|
||||
|
||||
public void setOndemandPort(int port);
|
||||
|
||||
public void setJaggrabPort(int port);
|
||||
|
||||
public void setMapLock(boolean maplock, int mapface);
|
||||
|
||||
public void setHPheads(boolean on);
|
||||
|
||||
public void setZoom(boolean on);
|
||||
|
||||
public void setKeyListener(java.awt.event.KeyListener kl);
|
||||
|
||||
public void modZoomInts(int zoom, int fwdbwd, int lftrit);
|
||||
|
||||
/**
|
||||
* Returns the server's port.
|
||||
* <p/>
|
||||
* This *MUST* be implemented correctly.
|
||||
*
|
||||
* @return The port the client would try to connect to, as set by setPort().
|
||||
*/
|
||||
public int getPort();
|
||||
|
||||
/*
|
||||
These are only meant to be called once.
|
||||
/**
|
||||
* Tells the client where the cache will reside, this is the only folder the client has write permissions to.
|
||||
* <p/>
|
||||
* This *MUST* be implemented correctly.
|
||||
*
|
||||
* @param cacheDir The directory the cache files for the client are in.
|
||||
*/
|
||||
public java.util.HashMap<String, String> getParams();
|
||||
public void setCacheDir(String cacheDir);
|
||||
|
||||
// should always return org.moparscape.userver.Server[2]
|
||||
/**
|
||||
* Gives the client a KeyListener to send left-over keyPressed events back to that the client doesn't recognize.
|
||||
* This is needed because the client grabs all key events and moparscape doesn't receive them,
|
||||
* causing the key bindings not to work. The way to implement this is to find your 'keyPressed(KeyEvent keyevent)'
|
||||
* method in your client, and at the end of it add 'client.keyListener.keyPressed(keyevent);', assuming
|
||||
* you save this 'kl' as client.keyListener.
|
||||
* <p/>
|
||||
* This *MUST* be implemented correctly.
|
||||
*
|
||||
* @param kl KeyListener to save and send events back to.
|
||||
*/
|
||||
public void setKeyListener(java.awt.event.KeyListener kl);
|
||||
|
||||
/**
|
||||
* Tells the client what port on localhost the Ondemand server is listening on.
|
||||
* If this client doesn't use this server, you can ignore this call.
|
||||
*
|
||||
* @param port The port the server is listening on on the localhost address.
|
||||
*/
|
||||
public void setOndemandPort(int port);
|
||||
|
||||
/**
|
||||
* Tells the client what port on localhost the Jaggrab server is listening on.
|
||||
* If this client doesn't use this server, you can ignore this call.
|
||||
*
|
||||
* @param port The port the server is listening on on the localhost address.
|
||||
*/
|
||||
public void setJaggrabPort(int port);
|
||||
|
||||
/**
|
||||
* Turns maplock on or off and also sets the direction the map should be locked to.
|
||||
* If you don't have this functionality, just ignore this call. (currently 508 does)
|
||||
*
|
||||
* @param maplock True for on, false for off.
|
||||
* @param mapface 0 for North, 1030 for South, 1545 for East, 515 for West. Look at 317 for reference.
|
||||
*/
|
||||
public void setMapLock(boolean maplock, int mapface);
|
||||
|
||||
/**
|
||||
* Turns HP over heads on or off.
|
||||
* If you don't have this functionality, just ignore this call. (currently 508 ignores it)
|
||||
*
|
||||
* @param on True for on, false for off.
|
||||
*/
|
||||
public void setHPheads(boolean on);
|
||||
|
||||
/**
|
||||
* Turns camera zoom on or off.
|
||||
* If you don't have this functionality, just ignore this call. (currently 508 ignores it)
|
||||
*
|
||||
* @param on True for on, false for off.
|
||||
*/
|
||||
public void setZoom(boolean on);
|
||||
|
||||
/**
|
||||
* Modifies the camera zoom and position.
|
||||
* For example functionality, look at moparscape's 317.
|
||||
* If you don't have this functionality, just ignore this call. (currently 508 ignores it)
|
||||
*
|
||||
* @param zoom The amount to add to the zoom integer.
|
||||
* @param fwdbwd The amount to add to the fwdbwd integer.
|
||||
* @param lftrit The amount to add to the lftrit integer.
|
||||
*/
|
||||
public void modZoomInts(int zoom, int fwdbwd, int lftrit);
|
||||
|
||||
|
||||
// The following are only meant to be called once.
|
||||
|
||||
/**
|
||||
* Moparscape feeds these parameters back to the client when it requests them, just like a browser would.
|
||||
* <p/>
|
||||
* This *MUST* be implemented correctly.
|
||||
*
|
||||
* @return A Map with the param name as the key, and the value as the value.
|
||||
*/
|
||||
public java.util.Map<String, String> getParams();
|
||||
|
||||
/**
|
||||
* Called once to get update servers for moparscape to start and manage.
|
||||
*
|
||||
* @param defaultLocation Default location of cache.
|
||||
* @param customLocation Custom location of cache.
|
||||
* @return Should always return org.moparscape.userver.Server[2] (but each index can be null)
|
||||
*/
|
||||
public org.moparscape.userver.Server[] getUpdateServers(String defaultLocation, String customLocation);
|
||||
|
||||
/**
|
||||
* Called to get the size of the client.
|
||||
* Currently moparscape ignores this and assumes it to be 765x503,
|
||||
* this will change in the near future though when support for
|
||||
* HD (and non-standard size SD) clients is added.
|
||||
*
|
||||
* @return Size of client.
|
||||
*/
|
||||
public java.awt.Dimension getDimension();
|
||||
|
||||
/**
|
||||
* Sets the background the client should use.
|
||||
* Optional, but much better if you use it.
|
||||
*
|
||||
* @param image Image to use as the client background.
|
||||
*/
|
||||
public void setBackground(java.awt.Image image);
|
||||
|
||||
}
|
||||
|
@ -21,6 +21,8 @@
|
||||
package org.moparscape.iface;
|
||||
|
||||
/**
|
||||
* This interface must be implemented for moparscape to load this as a server.
|
||||
* For two different working examples, check the 317 and 508 clients implementing this interface.
|
||||
* @author mopar
|
||||
*/
|
||||
public interface ServerInterface {
|
||||
|
@ -24,7 +24,6 @@ import org.moparscape.MainPanel;
|
||||
|
||||
import java.security.Permission;
|
||||
import java.security.Permissions;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
@ -33,7 +32,9 @@ import java.util.Map;
|
||||
*/
|
||||
public class SecurityManager extends java.lang.SecurityManager {
|
||||
|
||||
private Map<ClassLoader, Permissions> permissionMap = new HashMap<ClassLoader, Permissions>();
|
||||
// IdentityHashMap is faster than HashMap and better in this case as the ClassLoader is the SAME OBJECT
|
||||
// and therefore will compare better and faster with == rather than the .equals() HashMap uses
|
||||
private Map<ClassLoader, Permissions> permissionMap = new java.util.IdentityHashMap<ClassLoader, Permissions>();
|
||||
|
||||
// single socket permission that is allowed
|
||||
private java.net.SocketPermission allowedSocket = new java.net.SocketPermission("localhost", "connect,accept,resolve");
|
||||
@ -43,14 +44,6 @@ public class SecurityManager extends java.lang.SecurityManager {
|
||||
private Permission reflectPerm = new java.lang.reflect.ReflectPermission("suppressAccessChecks");
|
||||
private Permission classLoaderPerm = new java.lang.RuntimePermission("createClassLoader");
|
||||
|
||||
public SecurityManager() {
|
||||
try {
|
||||
new java.net.URL("http://localhost/");
|
||||
} catch (Exception e) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public void addPermissions(ClassLoader cl, Permissions perms) {
|
||||
// if they can't set the SecurityManager, they shouldn't be able to modify this one, so check...
|
||||
System.getSecurityManager().checkPermission(new java.lang.RuntimePermission("setSecurityManager"));
|
||||
@ -90,14 +83,10 @@ public class SecurityManager extends java.lang.SecurityManager {
|
||||
// this isn't ready to go live yet, so just return and allow it all
|
||||
//if (true) return;
|
||||
|
||||
// if this is the allowed socket, allow it
|
||||
if (allowedSocket.implies(perm))
|
||||
return;
|
||||
// we are now going to go through the ClassLoaders of all Classes on the stack
|
||||
// if any of them are in perms, then check the permissions, sticking to the most
|
||||
// restrictive of the permissions of any class in the stack (ANDing them all together)
|
||||
// so default value should be true or it would never be true ((false & anything) == false)
|
||||
boolean allow = true;
|
||||
// restrictive of the permissions of any class in the stack (if any are false, deny the request)
|
||||
|
||||
// get all classes on stack
|
||||
Class c[] = getClassContext();
|
||||
|
||||
@ -106,17 +95,26 @@ public class SecurityManager extends java.lang.SecurityManager {
|
||||
if (c[2].getName().equals("org.moparscape.security.SecurityManager"))
|
||||
return;
|
||||
|
||||
//System.out.println("requesting perm: "+perm);
|
||||
//System.out.println("requesting perm: " + perm);
|
||||
|
||||
for (int i = 1; i < c.length; i++) {
|
||||
ClassLoader cl = c[i].getClassLoader();
|
||||
// if the ClassLoader is null (can it be?) continue...
|
||||
if (cl == null)
|
||||
continue;
|
||||
|
||||
// getClassLoader() can return null, if it is the bootstrap class
|
||||
// loader, since our Map implementation handles nulls, go ahead
|
||||
// and ignore whether or not it is null (my tests show speed is the same)
|
||||
//if (cl == null) continue;
|
||||
|
||||
Permissions clPerms = permissionMap.get(cl);
|
||||
// if the classloader isn't in our map, we don't have any say on it so continue
|
||||
if (clPerms == null)
|
||||
continue;
|
||||
|
||||
// if the permissions allows this, continue and avoid all the following time-consuming checks
|
||||
// TODO: I've since discovered .implies() is rather slow, so find out what is slower, this or the following...
|
||||
if (clPerms.implies(perm))
|
||||
continue;
|
||||
|
||||
// 2 exceptions here for java.util.GregorianCalendar, java.util.Calendar, java.text.SimpleDateFormat:
|
||||
// java.lang.RuntimePermission accessClassInPackage.sun.util.resources
|
||||
// java.lang.reflect.ReflectPermission suppressAccessChecks
|
||||
@ -152,26 +150,27 @@ public class SecurityManager extends java.lang.SecurityManager {
|
||||
return;
|
||||
}
|
||||
}
|
||||
// it must be in our map, so update allow appropriatly
|
||||
allow &= clPerms.implies(perm);
|
||||
|
||||
// one last check, which I found is very slow
|
||||
// if this is the allowed socket, allow it
|
||||
if (allowedSocket.implies(perm))
|
||||
return;
|
||||
|
||||
// if we get all the way down here, the permission was denied and wasn't an exception, so throw an exception
|
||||
System.err.println("denying: " + perm.toString());
|
||||
|
||||
if (org.moparscape.MainPanel.debug()) {
|
||||
// class stack for debugging
|
||||
for (int x = 1; x < c.length; x++) System.out.println(x + ": " + c[x].getName());
|
||||
|
||||
Thread.dumpStack();
|
||||
}
|
||||
|
||||
// otherwise allow is false, throw a SecurityException
|
||||
throw new SecurityException("Permission denied: " + perm.toString());
|
||||
//return;
|
||||
}
|
||||
|
||||
// if allow is true, just return to allow the permission
|
||||
if (allow)
|
||||
return;
|
||||
|
||||
|
||||
System.err.println("denying: " + perm.toString());
|
||||
|
||||
if (org.moparscape.MainPanel.debug()) {
|
||||
// class stack for debugging
|
||||
for (int i = 1; i < c.length; i++) System.out.println(i + ": " + c[i].getName());
|
||||
|
||||
Thread.dumpStack();
|
||||
}
|
||||
|
||||
// otherwise allow is false, throw a SecurityException
|
||||
//throw new SecurityException("Permission denied: " + perm.toString());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
Loading…
Reference in New Issue
Block a user