Source code: com/untrusted/script/UntrustedScriptHandler.java
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 }
295