This is a brief rundown of especially the commands described in the [[http://java.sun.com/docs/books/tutorial/security1.2/index.html|Java Security Trail]]. For full understanding, read the trail. == Policy files == Security policies are stored in "policy files". These need to be included either by adding to the `$JAVA_HOME/lib/security/java.security` file or by using the `-Djava.security.policy=` option when starting Java. For the former, add a line `policy.url.`''n''`=` where ''n'' is a consecutive integer keeping multiple `policy.url` entries distinct. The policy files can be edited using the `policytool` program that comes with Java. The trail describes how the 1.5 tool works, the 1.6 tool has less keystore-related functionality. Permissions to do "stuff" can be granted either to code from a particular "!CodeBase" (URL of the files) or to code signed by a certificate. For a !CodeBase, permission can be granted to a URL and all subdirectories thereof by adding '-' to the URL, e.g. http://netarkivet.dk/- to specify permissions for anything from netarkivet.dk. Permissions are organized by class, e.g. !FilePermission controls read/write/execute permissions for files. All permissions have a target, e.g. a file or directory for !FilePermission. The syntax of the target is defined by the permission class. For !FilePermission, it is simply a file. Again, permission for all subdirectories can be given by adding a '-' after the file. Note also that properties can be used in the target, such as ${user.home}. The Trail mentions that on Unix there may be some [[http://java.sun.com/docs/books/tutorial/security/tour1/step3.html|DNS-related hacks required]]. I didn't find this necessary on an Ubuntu 7.10 box. Java ''applets'' by default have a security manager installed, but Java ''applications'' do not. To use a security manager, run Java with `-Djava.security.manager` option. [[http://java.sun.com/docs/books/tutorial/security/tour2/examples/java.policy|Default policy]] is to let anyone listen to any port > 1024 and to allow reading some specific properties like java.vendor.name, os.name etc. The policy tool is fairly simple to use. For example, to create a file read policy for code from a given URL, run `policytool`, click `Add policy entry`, enter the URL at !CodeBase, click `Add permission`, select `!FilePermission`, enter the relevant file at `Target`, select `read` under `actions`, click `Ok`, click `Done`, pick `Save` menu item and save the policy under whatever name you like. The file saved there is the one that needs to be specified in the `java.security` file or on the command line with `-Djava.security.policy`. == Certificates == We will be using certificates at least to allow our code to 1) write new files to the bitarchive, and 2) perform the correction action. Other people's code may not be given the rights to even create files, they may only get to write to a given !OutputStream. We won't need an infrastructure to accept arbitrary certificates, just to accept our own, which can be done during deployment. Signing happens at the jar file level using the `jarsigner` tool. It requires a key, of course, which can be made with `keytool -genkey`. I'll leave certificate authorities out of this. Creating a key can be done with `keytool -genkey -alias signFiles -keystore ourstore`. The alias is arbitrary and here indicates what the key is meant to be used for. The keystore is the file that the key is stored in. Both the key and the keystore will be password protected. `keytool` will ask for these passwords. It will also ask for some identifying information such as name, organization etc. The keystore generated (named with the -keystore option) is valid for 90 days unless the -validity option is used. A jar file can be signed by using `jarsigner -keystore ourstore -signedjar SignedFile.jar File.jar signFiles` where `SignedFile.jar` is the output file, `File.jar` is the input jar file, and `ourstore` is the keystore generated earlier. This, unsurprisingly, creates the `SignedFile.jar` file, but it will first ask for the keystore password and the key password. This signed jar file can now be sent/installed somewhere just like a normal jar file. To make use of the signing, the public key needs to be installed in the target system. The command `keytool -export -keystore ourstore -alias signFiles -file OurCert.cer` extracts the ''public'' signFiles key from ourstore into the !OurCert.cer file, prompting for the keystore password. In order to use this public key, the receiver (target system, in our case) will need to import it into a keystore using `keytool -import -alias sender -file OurCert.cer -keystore systemstore`. If `systemstore` doesn't exist yet, `keytool` will ask for a keystore password for it. The alias `sender` has no connection with the alias used during creation of the key. This will also print out some fingerprinting information. The fingerprints can be read from the certificate file using `keytool -printcert -file OurCert.cer`. To use this keystore in policies, use the `policytool` and choose the `Change keystore` menu item. Then input the location of the `systemstore` keystore as a URL and press `OK`. You can now, when making new policy entries, use the alias specified when importing the key (`sender`, in our case) in the `Signed by` field, optionally in combination with a !CodeBase. The remaining part of creating and adding a policy works just like when using only a !CodeBase entry above. == Notes for our implementation == We need to either run all of bitarchive under one security manager, or else apply a security manager to anything that comes from the outside. The former method requires that a number of things that our code does, like logging, connection to JMS, registering JMX beans etc, will have to be explicitly allowed in the security profile. The latter approach requires more code changes and doesn't prevent errors in the bitarchive from damaging the archive. Unfortunately, the security policies are not fine-grained enough that they can define e.g. that only the !RemoveAndGetOneFile method can move files away from the filedir directory, so the actual protection given by running a security policy on everything is somewhat limited. It's not possible to allow creation/moving/rewriting separately, those are all considered writes.