Return-Path: Delivered-To: apmail-xml-batik-dev-archive@xml.apache.org Received: (qmail 1851 invoked by uid 500); 17 Jun 2002 08:07:41 -0000 Mailing-List: contact batik-dev-help@xml.apache.org; run by ezmlm Precedence: bulk List-Post: List-Help: List-Unsubscribe: List-Subscribe: Reply-To: batik-dev@xml.apache.org Delivered-To: mailing list batik-dev@xml.apache.org Received: (qmail 1840 invoked by uid 500); 17 Jun 2002 08:07:41 -0000 Delivered-To: apmail-xml-batik-cvs@apache.org Date: 17 Jun 2002 08:07:39 -0000 Message-ID: <20020617080739.92817.qmail@icarus.apache.org> From: vhardy@apache.org To: xml-batik-cvs@apache.org Subject: cvs commit: xml-batik/sources/org/apache/batik/util ApplicationSecurityEnforcer.java X-Spam-Rating: daedalus.apache.org 1.6.2 0/1000/N vhardy 2002/06/17 01:07:39 Modified: resources/org/apache/batik/apps/svgbrowser/resources GUI.properties svgbrowser.bin.policy svgbrowser.policy sources/org/apache/batik/apps/svgbrowser Main.java PreferenceDialog.java sources/org/apache/batik/util ApplicationSecurityEnforcer.java Added: test-resources/org/apache/batik/bridge scriptPermissions.svg Log: Additional Configuration options for security settings in Squiggle. Now, it is possible to: - Enable/Disable secure scripting - When secure scripting is enabled, scripts have a limited set of permissions. Two permissions can be granted optionally: + access to the file system + access to the network with no limitations A finer granularity can be achieved by specifying a custom security policy file through the command line option (the java.security.policy system property). A custom security policy file will take precedence over the one generated by Squiggle. Revision Changes Path 1.1 xml-batik/test-resources/org/apache/batik/bridge/scriptPermissions.svg Index: scriptPermissions.svg =================================================================== Click on one of the following buttons to test unsecure content insertion (the result depends on the security settings) Network Access File System Access 1.52 +8 -3 xml-batik/resources/org/apache/batik/apps/svgbrowser/resources/GUI.properties Index: GUI.properties =================================================================== RCS file: /home/cvs/xml-batik/resources/org/apache/batik/apps/svgbrowser/resources/GUI.properties,v retrieving revision 1.51 retrieving revision 1.52 diff -u -r1.51 -r1.52 --- GUI.properties 14 Jun 2002 13:12:25 -0000 1.51 +++ GUI.properties 17 Jun 2002 08:07:38 -0000 1.52 @@ -403,7 +403,10 @@ PreferenceDialog.label.show.debug.trace = Show Debug Trace PreferenceDialog.label.selection.xor.mode = Display selection overlay using XOR mode PreferenceDialog.label.is.xml.parser.validating = Use a validating XML parser -PreferenceDialog.label.enforce.secure.scripting = Enforce secure scripting +PreferenceDialog.label.enforce.secure.scripting = Enforce secure scripting: +PreferenceDialog.label.secure.scripting.toggle = On +PreferenceDialog.label.grant.script.file.access = Grant scripts access to file system +PreferenceDialog.label.grant.script.network.access = Grant scripts access to all network PreferenceDialog.label.load.java = Java jar files PreferenceDialog.label.load.ecmascript = Ecmascript/Javascript PreferenceDialog.label.constrain.script.origin = Scripts constrained to same origin as document @@ -419,7 +422,9 @@ PreferenceDialog.label.origin.none = Not allowed PreferenceDialog.label.script.origin = Script Origin: PreferenceDialog.label.resource.origin = External Resources Origin: -PreferenceDialog.title.behavior = Optional Browser Behaviors +PreferenceDialog.title.browser.options = Browser Options +PreferenceDialog.title.behavior = Optional Behaviors +PreferenceDialog.title.security = Security Settings PreferenceDialog.title.network = Network Options PreferenceDialog.title.dialog = Preferences 1.6 +3 -0 xml-batik/resources/org/apache/batik/apps/svgbrowser/resources/svgbrowser.bin.policy Index: svgbrowser.bin.policy =================================================================== RCS file: /home/cvs/xml-batik/resources/org/apache/batik/apps/svgbrowser/resources/svgbrowser.bin.policy,v retrieving revision 1.5 retrieving revision 1.6 diff -u -r1.5 -r1.6 --- svgbrowser.bin.policy 14 May 2002 09:42:23 -0000 1.5 +++ svgbrowser.bin.policy 17 Jun 2002 08:07:38 -0000 1.6 @@ -1,3 +1,6 @@ +/* AUTOMATICALLY GENERATED */ +/* DO NOT EDIT */ + grant codeBase "${app.jar.base}/lib/crimson-parser.jar" { permission java.security.AllPermission; }; 1.5 +1 -1 xml-batik/resources/org/apache/batik/apps/svgbrowser/resources/svgbrowser.policy Index: svgbrowser.policy =================================================================== RCS file: /home/cvs/xml-batik/resources/org/apache/batik/apps/svgbrowser/resources/svgbrowser.policy,v retrieving revision 1.4 retrieving revision 1.5 diff -u -r1.4 -r1.5 --- svgbrowser.policy 14 May 2002 08:57:32 -0000 1.4 +++ svgbrowser.policy 17 Jun 2002 08:07:38 -0000 1.5 @@ -1,4 +1,4 @@ -/* AUTOMATICALLY GENERATED ON Wed Apr 17 13:44:15 CEST 2002*/ +/* AUTOMATICALLY GENERATED */ /* DO NOT EDIT */ grant codeBase "${app.dev.base}/classes/" { 1.35 +126 -8 xml-batik/sources/org/apache/batik/apps/svgbrowser/Main.java Index: Main.java =================================================================== RCS file: /home/cvs/xml-batik/sources/org/apache/batik/apps/svgbrowser/Main.java,v retrieving revision 1.34 retrieving revision 1.35 diff -u -r1.34 -r1.35 --- Main.java 14 Jun 2002 13:12:24 -0000 1.34 +++ Main.java 17 Jun 2002 08:07:39 -0000 1.35 @@ -13,9 +13,14 @@ import java.awt.event.ActionEvent; + +import java.io.BufferedReader; import java.io.File; +import java.io.FileWriter; import java.io.IOException; - +import java.io.InputStreamReader; +import java.io.Reader; +import java.io.Writer; import java.security.Policy; import java.util.HashMap; @@ -68,6 +73,44 @@ = ".load"; /** + * User home property + */ + public static final String PROPERTY_USER_HOME = "user.home"; + + /** + * System property for specifying an additional policy file. + */ + public static final String PROPERTY_JAVA_SECURITY_POLICY + = "java.security.policy"; + + /** + * Batik configuration sub-directory + */ + public static final String BATIK_CONFIGURATION_SUBDIRECTORY = ".batik"; + + /** + * Name of the Squiggle configuration file + */ + public static final String SQUIGGLE_CONFIGURATION_FILE = "preferences.xml"; + + /** + * Name of the Squiggle policy file + */ + public static final String SQUIGGLE_POLICY_FILE = "__svgbrowser.policy"; + + /** + * Entry for granting network access to scripts + */ + public static final String POLICY_GRANT_SCRIPT_NETWORK_ACCESS + = "grant {\n permission java.net.SocketPermission \"*\", \"listen, connect, resolve, accept\";\n};\n\n"; + + /** + * Entry for granting file system access to scripts + */ + public static final String POLICY_GRANT_SCRIPT_FILE_ACCESS + = "grant {\n permission java.io.FilePermission \"<>\", \"read\";\n};\n\n"; + + /** * Creates a viewer frame and shows it.. * @param args The command-line arguments. */ @@ -124,6 +167,14 @@ protected String[] arguments; /** + * Controls whether the application can override the + * system security policy property. This is done when there + * was no initial security policy specified when the application + * stated, in which case Batik will use that property. + */ + protected boolean overrideSecurityPolicy = false; + + /** * Script security enforcement is delegated to the * security utility */ @@ -181,6 +232,10 @@ Boolean.FALSE); defaults.put(PreferenceDialog.PREFERENCE_KEY_ENFORCE_SECURE_SCRIPTING, Boolean.TRUE); + defaults.put(PreferenceDialog.PREFERENCE_KEY_GRANT_SCRIPT_FILE_ACCESS, + Boolean.FALSE); + defaults.put(PreferenceDialog.PREFERENCE_KEY_GRANT_SCRIPT_NETWORK_ACCESS, + Boolean.FALSE); defaults.put(PreferenceDialog.PREFERENCE_KEY_LOAD_JAVA, Boolean.TRUE); defaults.put(PreferenceDialog.PREFERENCE_KEY_LOAD_ECMASCRIPT, @@ -196,10 +251,10 @@ SQUIGGLE_JAR_NAME); try { - preferenceManager = new XMLPreferenceManager("preferences.xml", + preferenceManager = new XMLPreferenceManager(SQUIGGLE_CONFIGURATION_FILE, defaults); - String dir = System.getProperty("user.home"); - File f = new File(dir, ".batik"); + String dir = System.getProperty(PROPERTY_USER_HOME); + File f = new File(dir, BATIK_CONFIGURATION_SUBDIRECTORY); f.mkdir(); preferenceManager.setPreferenceDirectory(f.getCanonicalPath()); preferenceManager.load(); @@ -250,12 +305,72 @@ }); c.setSize(100, 100); c.loadSVGDocument(Main.class.getResource("resources/init.svg").toString()); - - } /** + * Installs a custom policy file in the '.batik' directory. This is initialized + * with the content of the policy file coming with the distribution + */ + public void installCustomPolicyFile() throws IOException { + String securityPolicyProperty + = System.getProperty(PROPERTY_JAVA_SECURITY_POLICY); + + if (overrideSecurityPolicy + || + securityPolicyProperty == null + || + "".equals(securityPolicyProperty)) { + // Access default policy file + ParsedURL policyURL = new ParsedURL(securityEnforcer.getPolicyURL()); + + // Override the user policy + String dir = System.getProperty(PROPERTY_USER_HOME); + File batikConfigDir = new File(dir, BATIK_CONFIGURATION_SUBDIRECTORY); + File policyFile = new File(batikConfigDir, SQUIGGLE_POLICY_FILE); + + // Copy original policy file into local policy file + Reader r = new BufferedReader(new InputStreamReader(policyURL.openStream())); + Writer w = new FileWriter(policyFile); + + char[] buf = new char[1024]; + int n = 0; + while ( (n=r.read(buf, 0, buf.length)) != -1 ) { + w.write(buf, 0, n); + } + + r.close(); + + // Now, append additional grants depending on the security + // settings + boolean grantScriptNetworkAccess + = preferenceManager.getBoolean + (PreferenceDialog.PREFERENCE_KEY_GRANT_SCRIPT_NETWORK_ACCESS); + boolean grantScriptFileAccess + = preferenceManager.getBoolean + (PreferenceDialog.PREFERENCE_KEY_GRANT_SCRIPT_FILE_ACCESS); + + if (grantScriptNetworkAccess) { + w.write(POLICY_GRANT_SCRIPT_NETWORK_ACCESS); + } + + if (grantScriptFileAccess) { + w.write(POLICY_GRANT_SCRIPT_FILE_ACCESS); + } + + w.close(); + + // We now use the JAVA_SECURITY_POLICY property, so + // we allow override on subsequent calls. + overrideSecurityPolicy = true; + + System.setProperty(PROPERTY_JAVA_SECURITY_POLICY, + policyFile.toURL().toString()); + + } + } + + /** * Runs the application. */ public void run() { @@ -490,7 +605,7 @@ } } - private void setPreferences() { + private void setPreferences() throws IOException { Iterator it = viewerFrames.iterator(); while (it.hasNext()) { setPreferences((JSVGViewerFrame)it.next()); @@ -501,10 +616,13 @@ System.setProperty("proxyPort", preferenceManager.getString (PreferenceDialog.PREFERENCE_KEY_PROXY_PORT)); + installCustomPolicyFile(); + securityEnforcer.enforceSecurity (preferenceManager.getBoolean (PreferenceDialog.PREFERENCE_KEY_ENFORCE_SECURE_SCRIPTING) ); + } private void setPreferences(JSVGViewerFrame vf) { 1.16 +82 -17 xml-batik/sources/org/apache/batik/apps/svgbrowser/PreferenceDialog.java Index: PreferenceDialog.java =================================================================== RCS file: /home/cvs/xml-batik/sources/org/apache/batik/apps/svgbrowser/PreferenceDialog.java,v retrieving revision 1.15 retrieving revision 1.16 diff -u -r1.15 -r1.16 --- PreferenceDialog.java 14 Jun 2002 13:12:24 -0000 1.15 +++ PreferenceDialog.java 17 Jun 2002 08:07:39 -0000 1.16 @@ -132,6 +132,15 @@ public static final String LABEL_ENFORCE_SECURE_SCRIPTING = "PreferenceDialog.label.enforce.secure.scripting"; + public static final String LABEL_SECURE_SCRIPTING_TOGGLE + = "PreferenceDialog.label.secure.scripting.toggle"; + + public static final String LABEL_GRANT_SCRIPT_FILE_ACCESS + = "PreferenceDialog.label.grant.script.file.access"; + + public static final String LABEL_GRANT_SCRIPT_NETWORK_ACCESS + = "PreferenceDialog.label.grant.script.network.access"; + public static final String LABEL_LOAD_JAVA = "PreferenceDialog.label.load.java"; @@ -171,9 +180,15 @@ public static final String LABEL_CANCEL = "PreferenceDialog.label.cancel"; + public static final String TITLE_BROWSER_OPTIONS + = "PreferenceDialog.title.browser.options"; + public static final String TITLE_BEHAVIOR = "PreferenceDialog.title.behavior"; + public static final String TITLE_SECURITY + = "PreferenceDialog.title.security"; + public static final String TITLE_NETWORK = "PreferenceDialog.title.network"; @@ -233,6 +248,12 @@ public static final String PREFERENCE_KEY_ENFORCE_SECURE_SCRIPTING = "preference.key.enforce.secure.scripting"; + public static final String PREFERENCE_KEY_GRANT_SCRIPT_FILE_ACCESS + = "preference.key.grant.script.file.access"; + + public static final String PREFERENCE_KEY_GRANT_SCRIPT_NETWORK_ACCESS + = "preferenced.key.grant.script.network.access"; + public static final String PREFERENCE_KEY_LOAD_ECMASCRIPT = "preference.key.load.ecmascript"; @@ -280,6 +301,10 @@ protected JCheckBox enforceSecureScripting; + protected JCheckBox grantScriptFileAccess; + + protected JCheckBox grantScriptNetworkAccess; + protected JCheckBox loadJava; protected JCheckBox loadEcmascript; @@ -350,6 +375,8 @@ isXMLParserValidating.setSelected(model.getBoolean(PREFERENCE_KEY_IS_XML_PARSER_VALIDATING)); enforceSecureScripting.setSelected(model.getBoolean(PREFERENCE_KEY_ENFORCE_SECURE_SCRIPTING)); + grantScriptFileAccess.setSelected(model.getBoolean(PREFERENCE_KEY_GRANT_SCRIPT_FILE_ACCESS)); + grantScriptNetworkAccess.setSelected(model.getBoolean(PREFERENCE_KEY_GRANT_SCRIPT_NETWORK_ACCESS)); loadJava.setSelected(model.getBoolean(PREFERENCE_KEY_LOAD_JAVA)); loadEcmascript.setSelected(model.getBoolean(PREFERENCE_KEY_LOAD_ECMASCRIPT)); @@ -422,6 +449,10 @@ isXMLParserValidating.isSelected()); model.setBoolean(PREFERENCE_KEY_ENFORCE_SECURE_SCRIPTING, enforceSecureScripting.isSelected()); + model.setBoolean(PREFERENCE_KEY_GRANT_SCRIPT_FILE_ACCESS, + grantScriptFileAccess.isSelected()); + model.setBoolean(PREFERENCE_KEY_GRANT_SCRIPT_NETWORK_ACCESS, + grantScriptNetworkAccess.isSelected()); model.setBoolean(PREFERENCE_KEY_LOAD_JAVA, loadJava.isSelected()); model.setBoolean(PREFERENCE_KEY_LOAD_ECMASCRIPT, @@ -611,7 +642,25 @@ = new JCheckBox(Resources.getString(LABEL_IS_XML_PARSER_VALIDATING)); enforceSecureScripting - = new JCheckBox(Resources.getString(LABEL_ENFORCE_SECURE_SCRIPTING)); + = new JCheckBox(Resources.getString(LABEL_SECURE_SCRIPTING_TOGGLE)); + + grantScriptFileAccess + = new JCheckBox(Resources.getString(LABEL_GRANT_SCRIPT_FILE_ACCESS)); + + grantScriptNetworkAccess + = new JCheckBox(Resources.getString(LABEL_GRANT_SCRIPT_NETWORK_ACCESS)); + + JGridBagPanel scriptSecurityPanel = new JGridBagPanel(); + scriptSecurityPanel.add(enforceSecureScripting, 0, 0, 1, 1, WEST, HORIZONTAL, 1, 0); + scriptSecurityPanel.add(grantScriptFileAccess, 1, 0, 1, 1, WEST, HORIZONTAL, 1, 0); + scriptSecurityPanel.add(grantScriptNetworkAccess, 1, 1, 1, 1, WEST, HORIZONTAL, 1, 0); + + enforceSecureScripting.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + grantScriptFileAccess.setEnabled(enforceSecureScripting.isSelected()); + grantScriptNetworkAccess.setEnabled(enforceSecureScripting.isSelected()); + } + }); loadJava = new JCheckBox(Resources.getString(LABEL_LOAD_JAVA)); @@ -619,9 +668,9 @@ loadEcmascript = new JCheckBox(Resources.getString(LABEL_LOAD_ECMASCRIPT)); - JPanel loadScriptPanel = new JPanel(); - loadScriptPanel.add(loadJava); - loadScriptPanel.add(loadEcmascript); + JGridBagPanel loadScriptPanel = new JGridBagPanel(); + loadScriptPanel.add(loadJava, 0, 0, 1, 1, WEST, NONE, 1, 0); + loadScriptPanel.add(loadEcmascript, 1, 0, 1, 1, WEST, NONE, 1, 0); JPanel scriptOriginPanel = new JPanel(); @@ -671,27 +720,43 @@ resourceOriginGroup.add(rb); resourceOriginPanel.add(rb); + JTabbedPane browserOptions = new JTabbedPane(); + // browserOptions.setBorder(BorderFactory.createEmptyBorder(5,5,5,5)); + p.add(showRendering, 0, 0, 2, 1, WEST, HORIZONTAL, 1, 0); p.add(autoAdjustWindow, 0, 1, 2, 1, WEST, HORIZONTAL, 1, 0); p.add(enableDoubleBuffering, 0, 2, 2, 1, WEST, HORIZONTAL, 1, 0); p.add(showDebugTrace, 0, 3, 2, 1, WEST, HORIZONTAL, 1, 0); p.add(selectionXorMode, 0, 4, 2, 1, WEST, HORIZONTAL, 1, 0); p.add(isXMLParserValidating, 0, 5, 2, 1, WEST, HORIZONTAL, 1, 0); - p.add(enforceSecureScripting, 0, 6, 2, 1, WEST, HORIZONTAL, 1, 0); - p.add(new JLabel(Resources.getString(LABEL_LOAD_SCRIPTS)), 0, 7, 1, 1, WEST, NONE, 0, 0); - p.add(loadScriptPanel, 1, 7, 1, 1, WEST, NONE, 1, 0); - p.add(new JLabel(Resources.getString(LABEL_SCRIPT_ORIGIN)), 0, 8, 1, 1, WEST, NONE, 0, 0); - p.add(scriptOriginPanel, 1, 8, 1, 1, WEST, NONE, 1, 0); + p.add(new JLabel(), 0, 11, 2, 1, WEST, BOTH, 1, 1); + + browserOptions.addTab(Resources.getString(TITLE_BEHAVIOR), p); + p.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10)); + + p = new JGridBagPanel(); + p.add(new JLabel(Resources.getString(LABEL_ENFORCE_SECURE_SCRIPTING)), 0, 6, 1, 1, NORTHWEST, NONE, 0, 0); + p.add(scriptSecurityPanel, 1, 6, 1, 1, WEST, NONE, 0, 0); + p.add(new JLabel(Resources.getString(LABEL_LOAD_SCRIPTS)), 0, 8, 1, 1, WEST, NONE, 0, 0); + p.add(loadScriptPanel, 1, 8, 1, 1, WEST, NONE, 1, 0); + p.add(new JLabel(Resources.getString(LABEL_SCRIPT_ORIGIN)), 0, 9, 1, 1, WEST, NONE, 0, 0); + p.add(scriptOriginPanel, 1, 9, 1, 1, WEST, NONE, 1, 0); p.add(new JLabel(Resources.getString(LABEL_RESOURCE_ORIGIN)), 0, 10, 1, 1, WEST, NONE, 0, 0); - p.add(resourceOriginPanel, 1, 10, 1, 1, WEST, NONE, 1, 0); + p.add(resourceOriginPanel, 1, 10, 1, 1, WEST, NONE, 1, 0); + p.add(new JLabel(), 0, 11, 2, 1, WEST, BOTH, 1, 1); - p.setBorder(BorderFactory.createCompoundBorder - (BorderFactory.createTitledBorder - (BorderFactory.createEtchedBorder(), - Resources.getString(TITLE_BEHAVIOR)), - BorderFactory.createEmptyBorder(10, 10, 10, 10))); + browserOptions.addTab(Resources.getString(TITLE_SECURITY), p); + p.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10)); - return p; + JGridBagPanel borderedPanel = new JGridBagPanel(); + borderedPanel.add(browserOptions, 0, 0, 1, 1, WEST, BOTH, 1, 1); + borderedPanel.setBorder(BorderFactory.createCompoundBorder + (BorderFactory.createTitledBorder + (BorderFactory.createEtchedBorder(), + Resources.getString(TITLE_BROWSER_OPTIONS)), + BorderFactory.createEmptyBorder(10, 10, 10, 10))); + + return borderedPanel; } protected Component buildNetwork(){ 1.8 +25 -12 xml-batik/sources/org/apache/batik/util/ApplicationSecurityEnforcer.java Index: ApplicationSecurityEnforcer.java =================================================================== RCS file: /home/cvs/xml-batik/sources/org/apache/batik/util/ApplicationSecurityEnforcer.java,v retrieving revision 1.7 retrieving revision 1.8 diff -u -r1.7 -r1.8 --- ApplicationSecurityEnforcer.java 29 May 2002 14:20:43 -0000 1.7 +++ ApplicationSecurityEnforcer.java 17 Jun 2002 08:07:39 -0000 1.8 @@ -146,10 +146,12 @@ } if (enforce) { - // We want to install a SecurityManager. - if (sm == null) { - installSecurityManager(); - } + // We first set the security manager to null to + // force reloading of the policy file in case there + // has been a change since it was last enforced (this + // may happen with dynamically generated policy files). + System.setSecurityManager(null); + installSecurityManager(); } else { if (sm != null) { System.setSecurityManager(null); @@ -159,6 +161,23 @@ } /** + * Returns the url for the default policy. This never + * returns null, but it may throw a NullPointerException + */ + public URL getPolicyURL() { + ClassLoader cl = appMainClass.getClassLoader(); + URL policyURL = cl.getResource(securityPolicy); + + if (policyURL == null) { + throw new NullPointerException + (Messages.formatMessage(EXCEPTION_NO_POLICY_FILE, + new Object[]{securityPolicy})); + } + + return policyURL; + } + + /** * Installs a SecurityManager on behalf of the application */ public void installSecurityManager(){ @@ -177,13 +196,7 @@ if (securityPolicyProperty == null || securityPolicyProperty.equals("")) { // Specify app's security policy in the // system property. - URL policyURL = cl.getResource(securityPolicy); - - if (policyURL == null) { - throw new NullPointerException - (Messages.formatMessage(EXCEPTION_NO_POLICY_FILE, - new Object[]{securityPolicy})); - } + URL policyURL = getPolicyURL(); System.setProperty(PROPERTY_JAVA_SECURITY_POLICY, policyURL.toString()); --------------------------------------------------------------------- To unsubscribe, e-mail: batik-dev-unsubscribe@xml.apache.org For additional commands, e-mail: batik-dev-help@xml.apache.org