Java Source Code: com.untrusted.script.UntrustedScriptHandler


   1: /*
   2: 
   3:    Copyright 1999-2003 The Apache Software Foundation 
   4: 
   5:    Licensed under the Apache License, Version 2.0 (the "License");
   6:    you may not use this file except in compliance with the License.
   7:    You may obtain a copy of the License at
   8: 
   9:        http://www.apache.org/licenses/LICENSE-2.0
  10: 
  11:    Unless required by applicable law or agreed to in writing, software
  12:    distributed under the License is distributed on an "AS IS" BASIS,
  13:    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14:    See the License for the specific language governing permissions and
  15:    limitations under the License.
  16: 
  17:  */
  18: package com.untrusted.script;
  19: 
  20: import org.apache.batik.script.ScriptHandler;
  21: import org.apache.batik.script.Window;
  22: 
  23: import org.apache.batik.dom.svg.SVGOMDocument;
  24: 
  25: import org.w3c.dom.*;
  26: import org.w3c.dom.events.*;
  27: 
  28: import java.awt.AWTPermission;
  29: import java.io.FilePermission;
  30: import java.io.SerializablePermission;
  31: import java.lang.reflect.ReflectPermission;
  32: import java.net.NetPermission;
  33: import java.net.SocketPermission;
  34: import java.net.URL;
  35: import java.security.AllPermission;
  36: import java.security.Permission;
  37: import java.security.SecurityPermission;
  38: import java.sql.SQLPermission;
  39: import java.util.PropertyPermission;
  40: import javax.sound.sampled.AudioPermission;
  41: 
  42: /**
  43:  * This class implements the ScriptHandler interface and represents an 
  44:  * example of untrusted code.
  45:  *
  46:  * It creates a number of Java Permissions and checks that access is denied.
  47:  * the tests fail if the Permissions are granted.
  48:  *
  49:  * The only thing that the class should be allowed to make is a connection
  50:  * back to the server that served the document containing this script.
  51:  *
  52:  * @author <a href="mailto:vhardy@apache.org">Vincent Hardy</a>
  53:  * @version $Id: UntrustedScriptHandler.java,v 1.4 2005/03/27 08:58:29 cam Exp $
  54:  */
  55:	  public class UntrustedScriptHandler implements ScriptHandler {
  56:    public static final String svgNS = "http://www.w3.org/2000/svg";
  57:
  58:    /**
  59:     * Path for the file tested with FilePermission
  60:     */
  61:    public static final String testedPath = "build.sh";
  62:
  63:    /**
  64:     * Host which is used for testing
  65:     */
  66:    public static final String testedHost = "nagoya.apache.org:8080";
  67:
  68:    /**
  69:     * Table of Permissions which will be tested.
  70:     */
  71:	      protected static Object[][] basePermissions = {
  72:        {"AllPermission", new AllPermission()}, 
  73:        {"FilePermission read", new FilePermission(testedPath, "read")}, 
  74:        {"FilePermission write", new FilePermission(testedPath, "write")}, 
  75:        {"FilePermission execute", new FilePermission(testedPath, "execute")}, 
  76:        {"FilePermission delete", new FilePermission(testedPath, "delete")}, 
  77:        // 1.4 {"ServicePermission", new ServicePermission("krbtgt/EXAMPLE.COM@EXAMPLE.COM", "initiate")}, 
  78:        {"SocketPermission accept", new SocketPermission(testedHost, "accept")}, 
  79:        {"SocketPermission connect", new SocketPermission(testedHost, "connect")}, 
  80:        {"SocketPermission listen", new SocketPermission(testedHost, "listen")}, 
  81:        {"SocketPermission resolve", new SocketPermission(testedHost, "resolve")}, 
  82:        {"AudioPermission play", new AudioPermission("play")}, 
  83:        {"AudioPermission record", new AudioPermission("record")}, 
  84:        {"AWTPermission accessClipboard", new AWTPermission("accessClipboard")}, 
  85:        {"AWTPermission accessEventQueue", new AWTPermission("accessEventQueue")}, 
  86:        {"AWTPermission listenToAllAWTEvents", new AWTPermission("listenToAllAWTEvents")}, 
  87:        {"AWTPermission showWindowWithoutWarningBanner", new AWTPermission("showWindowWithoutWarningBanner")}, 
  88:        {"AWTPermission readDisplayPixels", new AWTPermission("readDisplayPixels")}, 
  89:        {"AWTPermission createRobot", new AWTPermission("createRobot")}, 
  90:        {"AWTPermission fullScreenExclusive", new AWTPermission("fullScreenExclusive")}, 
  91:        // 1.4 {"DelegationPermission", new DelegationPermission()}, 
  92:        // 1.4 {"LoggingPermission", new LoggingPermission("control")}, 
  93:        {"NetPermission setDefaultAuthenticator", new NetPermission("setDefaultAuthenticator")}, 
  94:        {"NetPermission requestPasswordAuthentication", new NetPermission("requestPasswordAuthentication")}, 
  95:        {"NetPermission specifyStreamHandler", new NetPermission("specifyStreamHandler")}, 
  96:        {"PropertyPermission java.home read", new PropertyPermission("java.home", "read")}, 
  97:        {"PropertyPermission java.home write", new PropertyPermission("java.home", "write")}, 
  98:        {"ReflectPermission", new ReflectPermission("suppressAccessChecks")}, 
  99:        {"RuntimePermission createClassLoader", new RuntimePermission("createClassLoader")}, 
 100:        {"RuntimePermission getClassLoader", new RuntimePermission("getClassLoader")}, 
 101:        {"RuntimePermission setContextClassLoader", new RuntimePermission("setContextClassLoader")}, 
 102:        {"RuntimePermission setSecurityManager", new RuntimePermission("setSecurityManager")}, 
 103:        {"RuntimePermission createSecurityManager", new RuntimePermission("createSecurityManager")}, 
 104:        {"RuntimePermission exitVM", new RuntimePermission("exitVM")}, 
 105:        {"RuntimePermission shutdownHooks", new RuntimePermission("shutdownHooks")}, 
 106:        {"RuntimePermission setFactory", new RuntimePermission("setFactory")}, 
 107:        {"RuntimePermission setIO", new RuntimePermission("setIO")}, 
 108:        {"RuntimePermission modifyThread", new RuntimePermission("modifyThread")}, 
 109:        {"RuntimePermission stopThread", new RuntimePermission("stopThread")}, 
 110:        {"RuntimePermission modifyThreadGroup", new RuntimePermission("modifyThreadGroup")}, 
 111:        {"RuntimePermission getProtectionDomain", new RuntimePermission("getProtectionDomain")}, 
 112:        {"RuntimePermission readFileDescriptor", new RuntimePermission("readFileDescriptor")}, 
 113:        {"RuntimePermission writeFileDescriptor", new RuntimePermission("writeFileDescriptor")}, 
 114:        {"RuntimePermission loadLibrary.{library name}", new RuntimePermission("loadLibrary.{library name}")}, 
 115:        {"RuntimePermission accessClassInPackage.java.security", new RuntimePermission("accessClassInPackage.java.security")}, 
 116:        {"RuntimePermission defineClassInPackage.java.lang", new RuntimePermission("defineClassInPackage.java.lang")}, 
 117:        {"RuntimePermission accessDeclaredMembers", new RuntimePermission("accessDeclaredMembers")}, 
 118:        {"RuntimePermission queuePrintJob", new RuntimePermission("queuePrintJob")}, 
 119:
 120:        {"SecurityPermission createAccessControlContext", new SerializablePermission("createAccessControlContext")}, 
 121:        {"SecurityPermission getDomainCombiner", new SerializablePermission("getDomainCombiner")}, 
 122:        {"SecurityPermission getPolicy", new SerializablePermission("getPolicy")}, 
 123:        {"SecurityPermission setPolicy", new SerializablePermission("setPolicy")}, 
 124:        {"SecurityPermission setSystemScope", new SerializablePermission("setSystemScope")}, 
 125:        {"SecurityPermission setIdentityPublicKey", new SerializablePermission("setIdentityPublicKey")}, 
 126:        {"SecurityPermission setIdentityInfo", new SerializablePermission("setIdentityInfo")}, 
 127:        {"SecurityPermission addIdentityCertificate", new SerializablePermission("addIdentityCertificate")}, 
 128:        {"SecurityPermission removeIdentityCertificate", new SerializablePermission("removeIdentityCertificate")}, 
 129:        {"SecurityPermission printIdentity", new SerializablePermission("printIdentity")}, 
 130:        {"SecurityPermission getSignerPrivateKey", new SerializablePermission("getSignerPrivateKey")}, 
 131:        {"SecurityPermission setSignerKeyPair", new SerializablePermission("setSignerKeyPair")}, 
 132:
 133:        {"SerializablePermission enableSubclassImplementation", new SerializablePermission("enableSubclassImplementation")},
 134:        {"SerializablePermission enableSubstitution", new SerializablePermission("enableSubstitution")},
 135:
 136:        {"SQLPermission", new SQLPermission("setLog")}, 
 137:
 138:        // 1.4 {"SSLPermission setHostnameVerifier", new SSLPermission("setHostnameVerifier")}
 139:        // 1.4{"SSLPermission getSSLSessionContext", new SSLPermission("getSSLSessionContext")}
 140:    };
 141:    
 142:    /**
 143:     * Set of Permissions to test. One is added if the Document is loaded from a host
 144:     */
 145:    private Object[][] permissions;
 146:
 147:    /**
 148:     * Reference to the rectangles which show the test status
 149:     */
 150:    private Element[] statusRects;
 151:
 152:    /**
 153:     * Runs this handler.  This method is called by the SVG viewer
 154:     * when the scripts are loaded.
 155:     * @param doc The current document.
 156:     * @param win An object which represents the current viewer.
 157:     */
 158:	      public void run(final Document doc, final Window win){
 159:        int nGrantedTmp = 0;
 160:
 161:        //
 162:        // If the document is loaded over the network, check that the
 163:        // class has permission to access the server
 164:        //
 165:        URL docURL = ((SVGOMDocument)doc).getURLObject();
 166:	          if (docURL != null && docURL.getHost() != null && !"".equals(docURL.getHost())) {
 167:            permissions = new Object[basePermissions.length + 3][2];
 168:            System.arraycopy(basePermissions, 0, 
 169:                             permissions, 3, basePermissions.length);
 170:
 171:            String docHost = docURL.getHost();
 172:	              if (docURL.getPort() != -1) {
 173:                docHost += ":" + docURL.getPort();
 174:            }
 175:
 176:            permissions[0][0] = "SocketPermission accept " + docHost;
 177:            permissions[0][1] = new SocketPermission(docHost, "accept");
 178:            permissions[1][0] = "SocketPermission connect " + docHost;
 179:            permissions[1][1] = new SocketPermission(docHost, "connect");
 180:            permissions[2][0] = "SocketPermission resolve " + docHost;
 181:            permissions[2][1] = new SocketPermission(docHost, "resolve");
 182:            nGrantedTmp = 3;
 183:        } else {
 184:            permissions = basePermissions;
 185:        }
 186:
 187:        // Captures the number of permissions which should be 
 188:        // granted to this code.
 189:        final int nGranted = nGrantedTmp;
 190:
 191:        //
 192:        // Build a table in the scrollable area of the document
 193:        //
 194:        Element securityResults = doc.getElementById("securityResults");
 195:        statusRects = new Element[permissions.length];
 196:
 197:	          for (int i=0; i<permissions.length; i++){
 198:            Element textElt = doc.createElementNS(svgNS, "text");
 199:            textElt.setAttributeNS(null, "x", "55");
 200:            textElt.setAttributeNS(null, "y", "" + (85 + i*20));
 201:            textElt.appendChild(doc.createTextNode(permissions[i][0].toString()));
 202:            securityResults.appendChild(textElt);
 203:
 204:            Element rectElt = doc.createElementNS(svgNS, "rect");
 205:            rectElt.setAttributeNS(null, "x", "50");
 206:            rectElt.setAttributeNS(null, "y", "" + (70 + i*20));
 207:            rectElt.setAttributeNS(null, "width", "330");
 208:            rectElt.setAttributeNS(null, "height", "20" );
 209:            rectElt.setAttributeNS(null, "class", "tableCell");
 210:            securityResults.appendChild(rectElt);
 211:
 212:            rectElt = doc.createElementNS(svgNS, "rect");
 213:            rectElt.setAttributeNS(null, "x", "380");
 214:            rectElt.setAttributeNS(null, "y", "" + (70 + i*20));
 215:            rectElt.setAttributeNS(null, "width", "20");
 216:            rectElt.setAttributeNS(null, "height", "20" );
 217:            rectElt.setAttributeNS(null, "class", "tableCell");
 218:            securityResults.appendChild(rectElt);
 219:
 220:            rectElt = doc.createElementNS(svgNS, "rect");
 221:            rectElt.setAttributeNS(null, "x", "383");
 222:            rectElt.setAttributeNS(null, "y", "" + (73 + i*20));
 223:            rectElt.setAttributeNS(null, "width", "14");
 224:            rectElt.setAttributeNS(null, "height", "14" );
 225:            rectElt.setAttributeNS(null, "class", "untested");
 226:            securityResults.appendChild(rectElt);
 227:
 228:            statusRects[i] = rectElt;
 229:        }
 230:
 231:        EventTarget testButton = (EventTarget)doc.getElementById("runTest");
 232:	          testButton.addEventListener("click", new EventListener() {
 233:	                  public void handleEvent(Event evt){
 234:                    SecurityManager sm = System.getSecurityManager();
 235:                    int successCnt = 0;
 236:
 237:	                      if (sm == null){
 238:	                          for (int i=0; i<nGranted; i++) {
 239:                            statusRects[i].setAttributeNS(null, "class", "passedTest");
 240:                            successCnt++;
 241:                        }
 242:	                          for (int i=nGranted; i<permissions.length; i++) {
 243:                            statusRects[i].setAttributeNS(null, "class", "failedTest");
 244:                        }
 245:                    }
 246:	                      else {
 247:	                          for (int i=0; i<nGranted; i++) {
 248:                            Permission p = (Permission)permissions[i][1];
 249:                            boolean success = true;
 250:	                              try {
 251:                                sm.checkPermission(p);
 252:                                statusRects[i].setAttributeNS(null, "class", "passedTest");
 253:                                successCnt++;
 254:                            } catch (SecurityException se){
 255:                                statusRects[i].setAttributeNS(null, "class", "failedTest");
 256:                                System.out.println("*********************************************");
 257:                                se.printStackTrace();
 258:                            }
 259:                        }
 260:
 261:	                          for (int i=nGranted; i<permissions.length; i++) {
 262:                            Permission p = (Permission)permissions[i][1];
 263:                            boolean success = true;
 264:	                              try {
 265:                                sm.checkPermission(p);
 266:                                statusRects[i].setAttributeNS(null, "class", "failedTest");
 267:                            } catch (SecurityException se){
 268:                                statusRects[i].setAttributeNS(null, "class", "passedTest");
 269:                                successCnt++;
 270:                            }
 271:                        }
 272:
 273:                    }
 274:
 275:                    // Update the global status
 276:                    Element globalStatus = doc.getElementById("globalStatus");
 277:	                      if ( successCnt == (statusRects.length) ) {
 278:                        globalStatus.setAttributeNS(null, "class", "passedTest");
 279:                    } else {
 280:                        globalStatus.setAttributeNS(null, "class", "failedTest");
 281:                    }
 282:                    
 283:                    String successRatioString = "Test Result: " + successCnt + " / " + statusRects.length;
 284:                    Element successRatio = doc.getElementById("successRatio");
 285:                    successRatio.replaceChild(doc.createTextNode(successRatioString),
 286:                                              successRatio.getFirstChild());
 287:                    
 288:                }
 289:            }, false);
 290:
 291:        
 292:    }
 293:
 294:}