# Tomcat SecurityManager setup with Unix

- Configuring Tomcat for use with a SecurityManager
- Starting Tomcat with a SecurityManager
- Trouble shooting tomcat.policy configuration and Security Violations

### Configuring Tomcat for use with a SecurityManager

tomcat.policy

The security policies implemented by the Java SecurityManager are configured in the `tomcat.policy` file located in the tomcat `conf` directory. The `tomcat.policy` file replaces any system `java.policy` file. The `tomcat.policy` file can be edited by hand or you can use the policytool application that comes with Java 1.2.

Entries in the `tomcat.policy` file use the standard `java.policy` file format as follows:

    // Example policy file entry

    grant [signedBy <signer> [,codeBase <code source>] {
        permission <class> [<name> [, <action list>]];
    };

The signedBy and codeBase entries are optional when granting permissions. Comment lines begin with `//` and end at a new line.

The codeBase is in the form of a URL and for a file URL can use the ${java.home} and ${tomcat.home} properties which are expanded out to the directory paths defined for them.

Default tomcat.policy file

    // Permissions for tomcat.

    // javac
    grant codeBase "file:${java.home}/../lib/-" {
      permission java.security.AllPermission;
    };

    // Tomcat gets all permissions
    grant codeBase "file:${tomcat.home}/lib/-" {
      permission java.security.AllPermission;
    };

    grant codeBase "file:${tomcat.home}/classes/-" {
      permission java.security.AllPermission;
    };

    // Example webapp policy
    // By default Tomcat grants read access on webapp dir and read of the
    // line.separator, path.separator, and file.separator PropertyPermissions.
    // Any permissions you grant here are in addition to the default.
    grant codeBase "file:${tomcat.home}/webapps/examples" {
      // Allow the example web application to read all java properties
      permission java.util.ProperyPermission "*", "read";
    };

Here is an example where in addition to the default permissions, we want to grant the examples web application the ability to connect to the localhost smtp port so that it can send mail.

    grant codeBase "file:${tomcat.home}/webapps/examples" {
      // Allow examples web application to use localhost smtp port
      permission java.net.SocketPermission "localhost:25","connect";
    };

If you want to set a default policy for all web applications you can use a grant entry without a URL. If we wanted to give all web applications not configured by their own grant entry some default permissions in addition to what Tomcat assigns we could do the following.

    grant {
      // Allow all web applications to read all java properties
      permission java.util.ProperyPermission "*", "read";
    };

Finally, a more complex tomcat.policy file. In this case we are using Tomcat as an app server for a number of remote web servers. We want to limit what remote web servers can connect to Tomcat by using the Java SecurityManager.

    // Permissions for tomcat.
    // javac needs this
    grant codeBase "file:${java.home}/lib/-" {
      permission java.security.AllPermission;
    };

    // Tomcat with IP filtering
    grant codeBase "file:${tomcat.home}/lib/-" {
      // Tomcat should be able to read/write all properties
      permission java.util.PropertyPermission "*","read,write";
      // Tomcat needs to be able to read files in its own directory
      permission java.io.FilePermission "${tomcat.home}/-","read";
      // Tomcat has to be able to write its logs
      permission java.io.FilePermission "${tomcat.home}/logs/-","read,write";
      // Tomcat has to be able to write to the conf directory
      permission java.io.FilePermission "${tomcat.home}/conf/-","read,write";
      // Tomcat has to be able to write to the webapps directory
      permission java.io.FilePermission "${tomcat.home}/webapps/-","read,write";
      // Tomcat has to be able to compile JSP's
      permission java.io.FilePermission "${tomcat.home}/work/-","read,write,delete";
      // Tomcat needs all the RuntimePermission's
      permission java.lang.RuntimePermission "*";
      // Needed so Tomcat can set security policy for a Context
      permission java.security.SecurityPermission "*";
      // Needed so that Tomcat will accept connections from a remote web server
      // Replace XXX.XXX.XXX.XXX with the IP address of the remote web server
      permission java.net.SocketPermission "XXX.XXX.XXX.XXX:1024-","accept,listen,resolve";
      // Tomcat has to be able to use its port on the localhost
      permission java.net.SocketPermission "localhost:1024-","connect,accept,listen,resolve";
    };

    // Example webapp policy
    // By default we grant read access on webapp dir
    // and read of the line.separator PropertyPermission
    grant codeBase "file:${tomcat.home}/webapps/examples" {
      permission java.net.SocketPermission "localhost:1024-","listen";
      permission java.util.PropertyPermission "*","read";
    };

server.xml

Uncomment out the entry in server.xml for the ContextInterceptor which defines the class named PolicyInterceptor.

### Starting Tomcat with a SecurityManager

Once you have configured the tomcat.policy and server.xml files for use with a SecurityManager, Tomcat can be started with the SecurityManager in place by using the "-security" option to bin/startup.sh.

## Trouble shooting tomcat.policy configuration and Security Violations

You can turn on Java SecurityManager debug logging by settting the environmental variable `TOMCAT_OPTS=-Djava.security.debug=all`. You will find the debug output in your `tomcat.log`.

JSP Compile using JVM internal javac fails with AccessControlException for RuntimePermission accessClassInPackage sun.tools.javac.

Check your JAVA_HOME/jre/lib/security/java.security file configuration. Comment out the line "package.access=sun.".

JSP Compile using JVM internal javac fails with AccessControlException for FilePermission read of tomcat work directory.

Try defining an absolute path for the codeBase needed in the policy grant for java itself instead of the ${java.home} property.

    // javac needs this
    grant codeBase "file:/usr/java/lib/-" {
      permission java.security.AllPermission;
    };