PageBox for Java: Web application deployment using Java PageBox

for
 PageBox for Java 
 API 
 Demo 
 Background 
Presentation Install User guide Developer guide Programming Port Repository PageBox Release notes

PageBox for Java installation

Objective

This page aims to answer three questions:

  1. Where to find PageBox?

  2. How to install and configure PageBox?

  3. How to diagnose PageBox problems?

Download

Documentation: pageboxHtml.jar.

Programming environment: pageboxPgm.jar. See the programming environment guide for a description of the programming environment of PageBox.

PageBox for Java is distributed in three versions, the JWSDP version, the Tomcat 4/Axis version and the Tomcat 5/Axis version. The three versions are identical except for their RPC invoker, stubs and configuration files. Releasing three versions allows avoiding confusions and manual settings and helps getting started.

JWSDP

Repository

Web archive (binaries)

repository.war

Sources

repositorySrc.jar

JavaDoc

repositoryDoc.jar

PageBox

PageBox is made of two parts:

  1. A shared library used by the PageBox Web archive and by the installed (PageBox-enabled) applications.

  2. The PageBox Web archive that handles the deployment requests and displays the administration forms

Library binaries

pageboxLib.jar

Library sources

pageboxLibSrc.jar

Library documentation

pageboxLibDoc.jar

Web archive binaries

pagebox.war

Web archive sources

pageboxSrc.jar

Web archive JavaDoc

pageboxDoc.jar

Generic installation class

Install.java

Tomcat 5 / Axis

Starting with version 0.1.0 there is a minor difference between the Tomcat 4 (servlet 2.3) and Tomcat 5 (servlet 2.4) versions. PageBox 0.1.0 and above can use the ServletRequestListener interface that was introduced in the servlet 2.4 specification. The version below uses this interface. The Tomcat 4 version does not use this interface. The only difference between both versions is located in the EventHandler class.

Repository

Web archive (binaries)

repository.war

Sources

repositorySrc.jar

JavaDoc

repositoryDoc.jar

PageBox

PageBox is made of two parts:

  1. A shared library used by the PageBox Web archive and by the installed (PageBox-enabled) applications.

  2. The PageBox Web archive that handles the deployment requests and displays the administration forms

Library binaries

pageboxLib.jar

Library sources

pageboxLibSrc.jar

Library documentation

pageboxLibDoc.jar

Web archive binaries

pagebox.war

Web archive sources

pageboxSrc.jar

Web archive JavaDoc

pageboxDoc.jar

Generic installation class

Install.java

Tomcat 4 / Axis

Repository

Web archive (binaries)

repository.war

Sources

repositorySrc.jar

JavaDoc

repositoryDoc.jar

PageBox

PageBox is made of two parts:

  1. A shared library used by the PageBox Web archive and by the installed (PageBox-enabled) applications.

  2. The PageBox Web archive that handles the deployment requests and displays the administration forms

Library binaries

pageboxLib.jar

Library sources

pageboxLibSrc.jar

Library documentation

pageboxLibDoc.jar

Web archive binaries

pagebox.war

Web archive sources

pageboxSrc.jar

Web archive JavaDoc

pageboxDoc.jar

Generic installation class

Install.java

WindowsCPU

On Windows NT, 2000, XP the measurement facility uses JNI and a dll called WindowsCPU.dll.

WindowsCPU.zip contains the sources and the project used to compile WindowsCPU.dll with Visual C++ 6.

DynDns

This servlet emulates the DynDns server and can be used to test modifications of the PageBox and of the PageBox repository. The code is the same for JWSDP and for Tomcat/Axis

Web archive

dyndns.war

Source

Update.java

Installation

The servlet container of the Java Web Services Developer pack (JWSDP) is Tomcat. Therefore the installation procedure for JWSDP is closely the same as for Tomcat/Axis.

We call the root directory of the servlet container $TOMCAT_ROOT in the explanation below and the directory where you download the archives $INSTALL.

JWSDP 1.3 is an all-in-one download containing the servlet container, the JAXP and the JAX-RPC support. Just go to http://java.sun.com/webservices/downloads/webservicespack.html, download JWSDP 1.3 and follow the installation instructions. JWSDP 1.5 does not include the servlet container. You can download a suitable version of Tomcat from http://java.sun.com/webservices/containers/tomcat_for_JWSDP_1_5.html.

In the case of the Tomcat version you need to download Tomcat (servlet container), Xalan (JAXP support) and Axis (JAX-RPC support). We briefly describe now the setup of Tomcat/Xalan/Axis.

Tomcat/Axis

Download

Download Tomcat from http://jakarta.apache.org/tomcat/index.html.

Download Xalan from http://xml.apache.org/xalan-j/index.html.

Download Axis from http://ws.apache.org/axis/index.html.

We tested PageBox 0.1.1 with Tomcat 5.0.28 or 4.1.31, Axis 1.1 and Xalan 2.5.2 or 2.5.1. You may use different versions of Tomcat and Xalan. If you use a different version of Axis you may need to regenerate the stub classes.

Tomcat

Inflate the Tomcat tar.

Axis

Inflate the Axis tar. We call the Axis installation directory $AXIS_ROOT.

Copy the archives stored in $AXIS_ROOT/lib or $AXIS_ROOT/webapps/axis/WEB-INF/lib into $TOMCAT_ROOT/common/lib.

Xalan

Inflate the Xalan tar. We call the Xalan installation directory $XALAN_ROOT.

Copy xalan.jar from $XALAN_ROOT/bin into $TOMCAT_ROOT/common/endorsed.

Repository

The installation consists of:

The simplest solution is to first inflate repository.war into $TOMCAT_ROOT/webapps/repository with the command:

cd $TOMCAT_ROOT/webapps/repository

jar xvf $INSTALL/repository.war

Then edit $TOMCAT_ROOT/webapps/repository/WEB-INF/web.xml. You should be displayed this (sections that you do not need to customize skipped):

<?xml version="1.0" encoding="ISO-8859-1"?>

<!DOCTYPE web-app

PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"

"http://java.sun.com/dtd/web-app_2_3.dtd">

<web-app>

<display-name>PageBoxRepository</display-name>

<description>PageBox Repository</description>

<!-- Directory of xml and log files -->

<context-param>

<param-name>workdir</param-name>

<param-value>C:\jakarta-tomcat-4.1.31\webapps\Repository</param-value>

</context-param>

<!-- Directory where the full archive is kept (a new subscriber receives archives from there) -->

<context-param>

<param-name>downloaddir</param-name>

<param-value>C:\jakarta-tomcat-4.1.31\webapps\Repository\download</param-value>

</context-param>

<!-- Directory where the archive is uploaded by PublishArchive -->

<context-param>

<param-name>uploaddir</param-name>

<param-value>C:\jakarta-tomcat-4.1.31\webapps\Repository\upload</param-value>

</context-param>

<!-- Directory where the jardiff are stored -->

<context-param>

<param-name>deltadir</param-name>

<param-value>C:\jakarta-tomcat-4.1.31\webapps\Repository\delta</param-value>

</context-param>

<context-param>

<param-name>deployer-class</param-name>

<param-value>Repository.AxisDeployer</param-value>

</context-param>

<context-param>

<param-name>RepoQuery-ws</param-name>

<param-value>/RepoQuery.jws</param-value>

</context-param>

<!-- Logging mode info or error -->

<context-param>

<param-name>logmode</param-name>

<param-value>info</param-value>

</context-param>

<!-- Above this value distribution with relay (bytes) -->

<context-param>

<param-name>ceiling</param-name>

<param-value>1500</param-value>

</context-param>

<!-- Unsafe time between relay deployment and changes (minutes) -->

<context-param>

<param-name>relaytime</param-name>

<param-value>60</param-value>

</context-param>

<context-param>

<param-name>dyndns-url</param-name>

<param-value>http://localhost:8080/nic/update</param-value>

</context-param>

<context-param>

<param-name>dyndns-user</param-name>

<param-value>pagebox1</param-value>

</context-param>

<context-param>

<param-name>dyndns-password</param-name>

<param-value>pagebox</param-value>

</context-param>

<context-param>

<param-name>dyndns-host</param-name>

<param-value>pagebox1.dyndns.org</param-value>

</context-param>

<context-param>

<param-name>dyndns-interface</param-name>

<param-value>ppp0</param-value>

</context-param>

<!-- Time between two retries (seconds) -->

<context-param>

<param-name>period</param-name>

<param-value>900</param-value>

</context-param>

<context-param>

<param-name>trust-store</param-name>

<param-value>C:\deployed\trustStore</param-value>

</context-param>

<context-param>

<param-name>trust-store-passwd</param-name>

<param-value>changeit</param-value>

</context-param>

<context-param>

<param-name>token-period</param-name>

<param-value>1000</param-value>

</context-param>

<listener><listener-class>Repository.EventHandler</listener-class></listener>

...

<resource-env-ref>

<description>

Link to the UserDatabase instance from which we request lists of

defined role names.

</description>

<resource-env-ref-name>users</resource-env-ref-name>

<resource-env-ref-type>

org.apache.catalina.UserDatabase

</resource-env-ref-type>

</resource-env-ref>

<security-constraint>

<web-resource-collection>

<web-resource-name>Subscriber</web-resource-name>

<url-pattern>/subscribe</url-pattern>

<url-pattern>/subscribe.jsp</url-pattern>

<url-pattern>/asubscribe</url-pattern>

<url-pattern>/asubscribe.jsp</url-pattern>

<url-pattern>/aselect</url-pattern>

<url-pattern>/aselect.jsp</url-pattern>

<url-pattern>/RepoQuery.jws</url-pattern>

<url-pattern>/hquery</url-pattern>

<http-method>GET</http-method>

<http-method>POST</http-method>

</web-resource-collection>

<auth-constraint>

<role-name>pagebox-subscriber</role-name>

</auth-constraint>

</security-constraint>

<security-constraint>

<web-resource-collection>

<web-resource-name>Publisher</web-resource-name>

<url-pattern>/publish</url-pattern>

<url-pattern>/publishArchive</url-pattern>

<url-pattern>/publish.jsp</url-pattern>

<url-pattern>/pageboxlist</url-pattern>

<url-pattern>/pageboxlist.jsp</url-pattern>

<url-pattern>/pageboxaudit</url-pattern>

<http-method>GET</http-method>

<http-method>POST</http-method>

</web-resource-collection>

<auth-constraint>

<role-name>pagebox-publisher</role-name>

</auth-constraint>

</security-constraint>

<security-constraint>

<web-resource-collection>

<web-resource-name>Audit</web-resource-name>

<url-pattern>/audit</url-pattern>

<http-method>GET</http-method>

<http-method>POST</http-method>

</web-resource-collection>

<auth-constraint>

<role-name>pagebox-admin</role-name>

</auth-constraint>

</security-constraint>

<login-config>

<auth-method>BASIC</auth-method>

<realm-name>PageBox repository</realm-name>

</login-config>

<security-role>

<role-name>pagebox-publisher</role-name>

</security-role>

<security-role>

<role-name>pagebox-subscriber</role-name>

</security-role>

<security-role>

<role-name>pagebox-admin</role-name>

</security-role>

</web-app>

You must define the initial logging level. In the web.xml example above the logging is set to info (informational or intensive). In info mode the Repository logs error, warning and information messages. You can also set the initial logging level to warn. In warn mode the Repository logs only error and warning messages.

Once the Repository application server is started you can change the logging level on the audit form.

ceiling is used for relayed deployment. In this model the Repository sends sets of target PageBoxes to relay PageBoxes. These PageBoxes in turn send sets of target PageBoxes to other relay PageBoxes. Because many sources deploy at the same time using different network paths the deployment is shorter for big archives. For small archives it is not necessarily the case because the relay PageBoxes must notify the Repository about the success of their deployments.

The optimal ceiling value depends on the bandwidth between the PageBoxes and the Repository. The recommended range is between 1500 and 63000 bytes.

relaytime is used for relay management. The archive is set in "maybe" status for all PageBoxes deployed by relay PageBoxes and then set in "installed" status by notify once the relay PageBoxes have completed their deployments. A Repository user cannot modify an archive in "maybe" status. After relaytime the Repository retries the deployment and sets the status according to the deployment status.

The optimal value depends on two factors:

The recommended range is between 5 and 60 minutes. The default value is 60 minutes.

period defines the time in seconds between two retries. At a retry the Repository

  1. Retries deployments failed for instance because the target PageBox was not running

  2. Handles the relay management as described above

  3. Checks that the IP address of the Repository has not changed. If the IP address has changed and if the DynDns parameters were set the Repository updates its address on the DynDns site.

The default value of period is 900s (15mn).

token-period is only used when PageBoxes registered on this Repository use the token API. token-period represents the time in milliseconds between the emission of two tokens. By default token-period equals 2000 (2 seconds).

We recommend setting the Repository listener with

<listener><listener-class>Repository.EventHandler</listener-class></listener>.

If you do not set the listener, set the subscribe servlet with <load-on-startup>110</load-on-startup>.

Web service

Starting with PageBox 0.0.10 the Repository can accommodate different RPC invokers and service access points. The protocol recommended for interoperability on Internet is SOAP 1.2. However you can implement your own protocol using for instance XML RPC, raw HTTP, RMI or raw TCP. Two parameters are defined in version 0.0.10, which should be sufficient for HTTP protocols:

Version 0.0.10 is packaged in three flavors to help getting started. We give now the values to setup for JWSDP, Tomcat/Axis and raw HTTP:

Flavor

Tomcat/Axis

JWSDP

Raw HTTP

deployer-class

Repository. AxisDeployer

Repository. JWSDPDeployer

Repository. HTTPDeployer

RepoQuery-ws

/RepoQuery.jws

/repoquery

/hquery

The default mode is JWSDP. The default values are therefore:

Repository directories

You need to customize the paths:

Name

Meaning

workdir

Directory where subscribers.xml, asubscribers.xml, archives.xml and log.html are written

uploaddir

Directory where Web archives are uploaded

downloaddir

Directory from where full Web archives are deployed

deltadir

Directory from where delta Web archives are deployed

When a Publisher publishes a Web archive the archive is first stored in uploaddir.

Then the Repository computes the difference between the old version of the archive stored in downloaddir and the new version stored in uploaddir. Next the Repository stores the difference in deltadir.

Eventually the Repository removes the old version and moves the new version of the archive into downloaddir.

If a subscribed PageBox has already the old version of the archive, the Repository deploys the difference from deltadir. If a subscribed PageBox does not have the old version of the archive, the Repository deploys the full archive from downloaddir.

Except during publications the uploaddir should be empty.

We present now the structure of the files written and updated by the Repository for troubleshooting purpose: you should never modify these files by hand.

archives.xml

archives.xml describes the archives published on a Repository. archives.xml is displayed by publish.jsp. It has the following format.

<archives>

<archive>

<name>testarch.jar</name>

<owner>tester</owner>

<doc></doc>

<date>2002-10-17 00:27:35</date>

<size>1068</size>

<ASinstall>true</ASinstall>

<delta>false</delta>

</archive>

</archives>

Each archive is represented by an archive element that contains:

Element

Meaning

name

Archive name as set by the Publisher. It is also the name of the archive in uploaddir, downloaddir and deltadir

owner

User ID of the Publisher who requested the upload

doc

URL of the Web archive documentation (set on the publish form)

date

Date when the archive was uploaded

size

Archive size

ASinstall

True if the archive should be deployed on the target application server

delta

True in case of jardiff upload (delta update)

subscribers.xml and asubscribers.xml

subscribers.xml describes the Repository subscribers and the deployment status of the archives on the subscribed PageBox. subscribers.xml is displayed by subscribe.jsp.

asubscribers.xml describes the archive subscribers of the Repository and the deployment status of the archives on the subscribed PageBox. asubscribers.xml is displayed by asubscribe.jsp and aselect.jsp.

subscribers.xml and asubscribers.xml have the same format [Axis example]:

<subscribers>

<subscriber>

<url> https://localhost:8443/PageBox/Deploy.jws</url>

<state>active</state>

<user>subscriber</user>

<pbuser>pagebox1</pbuser>

<pbpasswd>pagebox</pbpasswd>

<rank>1</rank>

<archives>

<archive>

<name>myarchive.jar</name>

<status>installed</status>

<maybe-expire>installed</maybe-expire>

</archive>

</archives>

</subscriber>

<downloadURL>https://localhost:8443/Repository/RepoQuery.jws</downloadURL>

</subscribers>

Each subscription is represented by a subscriber element that contains:

Element

Meaning

url

URI of the deployment Web service of the target PageBox

state

"active" or "pending remove". If a subscriber unsubscribes a PageBox that cannot be contacted the subscription is put in "pending remove" state. The Repository retries periodically to undeploy the PageBox Web archives. Therefore this state should only temporarily exist.

user

User ID of the Subscriber who subscribed the target PageBox

pbuser

Account ID to use to connect to the target PageBox

pbpasswd

Account password to use to connect to the target PageBox

rank

Rank used to select the relay PageBoxes (not yet used)

The status of a Web archive deployment on a subscribed PageBox is represented by an archive element:

Element

Meaning

name

Name of the Web archive

status

"installed", "error", "maybe", "pending", "pending remove", "maybe remove". If the Repository is unable to call the undeploy method of the PageBox Web service the archive is put in "pending remove" state. If the Repository is unable to call the deploy method of the PageBox Web service the archive is put in "pending" state. If the Repository deploys the archive with relays the archive is in "maybe" state up to the time the Repository receives the corresponding notify call. The Repository retries periodically to deploy the archives in "pending" state and to undeploy the archives in "pending remove" state. If the undeploy method returns an error the archive is put in "error" state, which can mean that the PageBox is not configured to allow the installation of this archive. "maybe remove" is a pending remove state when the archive should be undeployed after relayTime.

maybe-expire

After this time a relayed deployment can be retried in "maybe" state or an undeployment can be tried in "maybe remove" state.

Repository security

Repository security relies on the user authentication and if needed on SSL.

The default security model (described in the web.xml listed above) assumes three roles:

Name

Authorizations

pagebox-publisher

Publish and unpublish archives. List its publications.

pagebox-subscriber

Subscribe and unsubscribe PageBoxes. List its subscriptions.

pagebox-admin

Show and clear log. List all publications and subscriptions.

The web.xml above uses basic authentication and the Tomcat user database. You can set the user database in $TOMCAT_ROOT/conf/tomcat-users.xml with:

<?xml version='1.0'?>

<tomcat-users>

<role rolename="admin"/>

<role rolename="manager"/>

<role rolename="provider"/>

<role rolename="pagebox-admin"/>

<role rolename="pagebox-publisher"/>

<role rolename="pagebox-subscriber"/>

<user username="pagebox" password="pagebox" roles="admin,manager,provider"/>

<user username="tester" password="tester" roles="pagebox-admin,pagebox-publisher,pagebox-subscriber"/>

<user username="subscriber" password="subscriber" roles="pagebox-subscriber"/>

<user username="publisher" password="publisher" roles="pagebox-publisher"/>

<user username="subscriber2" password="subscriber" roles="pagebox-subscriber"/>

<user username="publisher2" password="publisher" roles="pagebox-publisher"/>

</tomcat-users>

In this example we define a pagebox account for the administration of Tomcat, a tester account to manage the log and all publications and subscriptions, two publisher accounts, publisher and publisher2 and two subscriber accounts, subscriber and subscriber2.

Note:

You must define the tester account with the pagebox-publisher and pagebox-subscriber roles to allow it to manage publications and subscriptions

SSL

Principle

The Secure Socket Layer (SSL) has three functions:

  1. Encryption: a man in the middle cannot read the sent archive

  2. Hashing: protection against tampering

  3. A PageBox that calls the Repository Web service checks that the remote server is a Repository server and not a fake server

The Repository automatically detects if SSL is in place with the following snippet:

String cypher = (String)request.getAttribute("javax.servlet.request.cipher_suite");

if (request.isSecure() && cypher.startsWith("SSL"))

...

Getting started

SSL setting is well described in a Tomcat how-to. Here is a summary. To use SSL you must

In Java key pairs and certificates are stored in keystore files.

For testing you can create the keystore, a key pair and a certificate with the following command:

keytool -genkey -alias tomcat -keyalg RSA

keytool asks many questions. If you want to simplify the subsequent Tomcat configuration step use the default password, which is "changeit" for the keystore and the key. Put down the Repository host name when keytool asks you to enter your first name and last name. Otherwise, you will encounter "HTTPS hostname wrong error" exception.

The Repository host name is:

The command above creates the default key if it does not already exist in a file named .keystore in the user's home directory, which is on Win 2K and XP Documents and Settings\username.

Now you can configure Tomcat to use SSL. Define a SSL connector in $TOMCAT_ROOT/conf/server.xml:

<-- Define an SSL HTTP/1.1 Connector on port 8443 -->

<!--

<Connector className="org.apache.catalina.connector.http.HttpConnector"

port="8443" minProcessors="5" maxProcessors="75"

enableLookups="true"

acceptCount="10" debug="0" scheme="https" secure="true">

<Factory className="org.apache.catalina.net.SSLServerSocketFactory"

clientAuth="false" protocol="TLS"/>

</Connector>

-->

If you want to prevent users to access the Repository without SSL comment the HTTP connector definition.

If you use a non-default keystore specify the keystore path in a keystoreFile attribute of the Factory element. If your keystore or certificate has a password different of changeit specify the password in a keystorePass attribute of the Factory element.

Production concern

Do not use “keytool -genkey -alias repository -keyalg RSA” on a production system. The reason is that this command generates a self-signed certificate, which basically says: “I certify that I am what I pretend to be”.

You need a certificate from a certificate authority. To get this certificate:

  1. Generate a PKCS#10 certificate request with the command keytool -certreq -alias tomcat

  2. Use this certificate request to get a certificate from a Certificate Authority

  3. Import the returned certificate in your keystore with the command keytool -import -file certificate_issued_by_CA -alias tomcat

The simplest solution is to use an Internet Certificate Authority, the most famous being Verisign and Thawte. You can also use InstantSSL. These CAs may grant you free certificates for testing purpose. For a trustable certificate you must pay. It has to be said that in this particular case that charging someone for a certificate is the cheapest way to get evidence that a requestor is who it claims to be: (1) the request knew a credit card number and expiration date (2) the requestor did not complain when it was charged for the service.

Another solution is to run a constellation certificate authority, the most popular commercial products being Netscape Management System and Microsoft Certificate service. The cheapest solution consists in using the CA command of OpenSSL. A cookbook explains how to do that.

On a production environment do not use the default password. If a malicious user can read your keystore and guess its password it can use your private key and your security is compromised.

PageBox checking

The PageBox may also use SSL. In this case the Repository checks the certificate presented by the PageBox to verify that the requestor is a valid PageBox and not a fake server. More precisely the Repository verifies that the issuer of the certificate presented by the PageBox is defined in a special keystore called a trust store.

By default this keystore is a file in the Sun jks format. A system property, javax.net.ssl.trustStore specifies its path and another system property javax.net.ssl.trustStorePassword specifies its password. For convenience and consistency we defined two context parameters in the Repository web.xml:

Name

System property

Meaning

trust-store

javax.net.ssl.trustStore

Path of the trust store

trust-store-passwd

javax.net.ssl.trustStorePassword

Password of the trust store

Note that these parameters are JVM-wide.

If you do not define javax.net.ssl.trustStore at Tomcat startup nor trust-store in the Repository web.xml then the implementation will use a $JAVA_HOME /lib/security/jssecacerts trust store if it exists and a $JAVA_HOME /lib/security/cacerts if not. Here $JAVA_HOME is the installation path of the runtime ($JDK_JAVA_HOME/jre).

cacert contains a limited number of trusted root certificates that you can display with the command:

keytool -list -keystore \j2sdk1.4.1\jre\lib\security\cacerts

The use of SSL for PageBox implies the same tasks as for the Repository:

  1. Create a public/private key pair. SSL will use the private key for signature and handshaking encryption.

  2. Create a certificate that certifies that the public key belongs to the PageBox. SSL will present the certificate to the Repository that tries to call the PageBox Web service.

  3. Configure the Tomcat hosting PageBox to use SSL with this certificate and private key

In the same way as for the Repository you can use self-signed certificates for the Tomcat hosts of the subscribed PageBox. However because each self-signed certificate has a unique issuer, the certificate itself, you must enter all Tomcat certificates in the trust store, which might be the simplest solution for testing but is inconvenient in a production environment.

In a production environment PageBox administrators should query a certificate to a constellation certificate authority. Then the administrator of a constellation Repository only needs to add the certificate of the certificate authority to the trust store.

In both cases:

  1. The Repository administrator creates the trust store but if it is happy with the default cacerts

  2. The certificate owner exports the certificate and sends it to the Repository administrator

  3. The Repository administrator imports the certificate in the trust store

To create the trust store you can use this command:

keytool -genkey -alias pagebox -keyalg RSA -keystore trustStore

To export a certificate stored in a keystore (typically a self-signed certificate) use this command:

keytool -export -alias tomcat -file pagebox.cer

To import a certificate in the trust store use this command:

keytool -import -v -trustcacerts -alias pageboxi -file pagebox.cer -keystore trustStore

DynDns

DynDns setting is defined by the following context parameters in the Repository web.xml:

Name

Meaning

Mandatory

dyndns-url

URL of the DynDNS registration service

Yes

dyndns-user

User used to connect to the DynDNS registration service

Yes

dyndns-password

Password used to connect to the DynDNS registration service

Yes

dyndns-host

DNS name to register

Yes

dyndns-interface

Network interface registered on the DynDNS registration service

No

dyndns-name

Local host name registered on the DynDNS registration service

No

If you want to use the dynamic registration facility you need:

Your host may have more than one IP address. To identify this IP address you can specify the local name for this IP address (specified in /etc/hosts on Linux/Unix and on \windows\System32\drivers\etc\hosts on Windows) or specify the interface name, for instance ppp0 for a dialup link on Windows. To list the interfaces defined on your system use the ipconfig command or use this Java class.

Sandbox

Starting with PageBox for Java version 0.0.7 the Repository is tested with Java 2 security.

To use this facility you must:

  1. Customize $TOMCAT_ROOT/conf/catalina.policy

  2. Start the servlet container with security. The security is not setup by default.

catalina.policy

You must restrict default permissions (that allow for instance to write everywhere) and give all permissions to PageBox, PageBoxLib and to extension archives.

We recommend to comment in default permissions (in grant { ... })

permission java.io.FilePermission "-", "read,write,delete";

Your Web applications will still be able to change files in their directories because Web applications are given a read/write/delete FilePermission for files and directories in their document root. If you need to grant file permissions to specific files you can add lines like:

permission java.io.FilePermission "E:/java/pandora/keystore", "read";

Note for Window users:

Use slashes and not backslashes in the file path.

You should also comment in default permissions Runtime permissions such as:

permission java.lang.RuntimePermission "loadLibrary";

permission java.lang.RuntimePermission "queuePrintJob";

You must grant all permissions to Repository:

grant codeBase "file:${catalina.home}/webapps/Repository/-" {

permission java.security.AllPermission;

};

Granting permissions to Repository is not an issue because you control this archive that you download and install and because you can check and recompile its sources.

Start

Start WSDP with:

%TOMCAT_ROOT%\bin\start.sh -security (Unix, Linux)

$TOMCAT_ROOT/bin/start.bat -security (Windows)

PageBox

The installation consists of:

PageBox library

There are two ways to use the PageBox library:

  1. As a shared library: the recommended (and, starting in version 0.0.7, secure) way

  2. As a archive library

With the latter method you must include the pageboxLib.jar in WEB-INF/lib of the web archives of PageBox and of all Web applications deployed with PageBox that provide an installation class or use the PageBox API. Therefore the deployment takes more time and uses more bandwidth and the Application server uses more memory.

To install the PageBox library as a shared library on JWSDP, copy pageboxLib.jar into $TOMCAT_ROOT/shared/lib.

To install the PageBox library as a shared library on Tomcat/Axis, copy pageboxLib.jar into $TOMCAT_ROOT/common/lib.

web.xml

The simplest solution is to first inflate pagebox.war into $TOMCAT_ROOT/webapps/pagebox with the command:

cd $TOMCAT_ROOT/webapps/pagebox

jar xvf $INSTALL/pagebox.war

Then edit $TOMCAT_ROOT/webapps/pagebox/WEB-INF/web.xml. You should be displayed this (sections that you do not need to customize skipped):

<?xml version="1.0" encoding="ISO-8859-1"?>

<!DOCTYPE web-app PUBLIC '-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN' 'http://java.sun.com/dtd/web-app_2_3.dtd'>

<web-app>

<display-name>PageBoxApplication</display-name>

<description>PageBox Application</description>

<context-param>

<param-name>workdir</param-name>

<param-value> C:\jakarta-tomcat-4.1.31\webapps\PageBox</param-value>

</context-param>

<context-param>

<param-name>Deploy-ws</param-name>

<param-value>/Deploy.jws</param-value>

</context-param>

<context-param>

<param-name>logmode</param-name>

<param-value>info</param-value>

</context-param>

<context-param>

<param-name>install-url</param-name>

<param-value>http://localhost:8080/manager</param-value>

</context-param>

<context-param>

<param-name>install-class</param-name>

<param-value>PageBox.TomcatInstall</param-value>

</context-param>

<context-param>

<param-name>install-user</param-name>

<param-value>pagebox</param-value>

</context-param>

<context-param>

<param-name>install-password</param-name>

<param-value>pagebox</param-value>

</context-param>

<context-param>

<param-name>dyndns-user</param-name>

<param-value>pagebox1</param-value>

</context-param>

<context-param>

<param-name>dyndns-password</param-name>

<param-value>pagebox</param-value>

</context-param>

<context-param>

<param-name>dyndns-host</param-name>

<param-value>pagebox1.dyndns.org</param-value>

</context-param>

<context-param>

<param-name>dyndns-name</param-name>

<param-value>pagebox1</param-value>

</context-param>

<context-param>

<param-name>period</param-name>

<param-value>900</param-value>

</context-param>

<context-param>

<param-name>trust-store</param-name>

<param-value>C:\deployed\trustStore</param-value>

</context-param>

<context-param>

<param-name>trust-store-passwd</param-name>

<param-value>changeit</param-value>

</context-param>

<context-param>

<param-name>token-period</param-name>

<param-value>2000</param-value>

</context-param>

<listener><listener-class>PageBox.EventHandler</listener-class></listener>

...

<resource-env-ref>

<description>

Link to the UserDatabase instance from which we request lists of

defined role names.

</description>

<resource-env-ref-name>users</resource-env-ref-name>

<resource-env-ref-type>

org.apache.catalina.UserDatabase

</resource-env-ref-type>

</resource-env-ref>

<security-constraint>

<web-resource-collection>

<web-resource-name>PageBoxUser</web-resource-name>

<url-pattern>/audit</url-pattern>

<url-pattern>/update </url-pattern>

<url-pattern>/Deploy.jws</url-pattern>

<url-pattern>/hdeploy</url-pattern>

<http-method>GET</http-method>

<http-method>POST</http-method>

</web-resource-collection>

<auth-constraint>

<role-name>pagebox-user</role-name>

</auth-constraint>

</security-constraint>

<login-config>

<auth-method>BASIC</auth-method>

<realm-name>PageBox</realm-name>

</login-config>

<security-role>

<role-name>pagebox-user</role-name>

</security-role>

</web-app>

We recommend setting the PageBox listener with

<listener><listener-class>PageBox.EventHandler</listener-class></listener>.

If you do not set the listener, set the Update servlet with <load-on-startup>110</load-on-startup>.

We describe below the context parameters you probably need to set.

Security parameters

The PageBox security relies on the user authentication.

The default security model (described in the web.xml listed above) assumes a pagebox-user role that allows

The web.xml uses basic authentication and the Tomcat user database. You can set the user database in $TOMCAT_ROOT/conf/tomcat-users.xml with:

<?xml version='1.0'?>

<tomcat-users>

<role rolename="admin"/>

<role rolename="manager"/>

<role rolename="provider"/>

<role rolename="pagebox-user"/>

<user username="pagebox" password="pagebox" roles="admin,manager,provider"/>

<user username="pagebox1" password="pagebox" roles="pagebox-user"/>

</tomcat-users>

workdir

workdir is the directory where you must define rules.xml (described below) and where log.html and PbArchives.xml are written and updated.

PbArchives.xml describes the archives installed on a PageBox. PbArchives.xml is displayed by update. It has the following format [JWSDP case].

<PbArchs>

<Archive>

<name>myarchive.jar</name>

<downloadURL>http://localhost:8080/repository/repoquery</downloadURL>

<owner>publisher1</owner>

<size>101024</size>

<date> 2002-10-17 00:27:35</date>

<docURL>http://localhost/home3/polaris/pol-index.html</docURL>

<install>true</install>

</Archive>

<url>http://localhost:8080/PageBox/deploy</url>

</PbArchs>

Each archive is represented by an Archive element that contains:

Element

Meaning

name

Archive name. The archive is inflated in a directory whose name is the archive name without extension

owner

User ID of the Publisher who requested the upload

docURL

URL of the Web archive documentation (set on the publish form)

date

Date when the archive was uploaded

size

Archive size

downloadURL

URL of the Repository’s RepoQuery Web service

install

true if the archive should be dynamically installed using the Application server deployer

url

URL of this PageBox Web service

We present now the structure of PbArchives.xml for troubleshooting purpose: you should never modify this file by hand.

info

You must define the initial logging level. In the web.xml example above the logging is set to info (informational or intensive). In info mode the PageBox logs error, warning and information messages. You can also set the initial logging level to warn. In warn mode the PageBox logs only error and warning messages.

Once the PageBox application server is started you can change the logging level on the audit form.

Dynamic deployment parameters

Once the deployed archive has been inflated and its Install class has been invoked the PageBox can call the dynamic configuration facility of the Application server. The dynamic configuration requires four context parameters in web.xml:

Context parameter

Meaning

install-class

Name of a class that calls the dynamic configuration. This class must implement the PageBox.ASInstallIF interface.

install-url

URL of the configuration facility

install-user

User ID to use to connect to the configuration facility

install-password

Password to use to connect to the configuration facility

PageBox.TomcatInstall is the Tomcat 4 installer.

If the base URL of your Tomcat installation is http://mysite:8080 the configuration facility URL is http://mysite:8080/manager. In case of Tomcat 4 install-user must identify a user with a manager role.

See the porting guide to develop a class to call the dynamic configuration of another Application server.

DynDns

Name

Meaning

Mandatory

dyndns-url

URL of the DynDNS registration service

Yes

dyndns-user

User used to connect to the DynDNS registration service

Yes

dyndns-password

Password used to connect to the DynDNS registration service

Yes

dyndns-host

DNS name to register

Yes

dyndns-interface

Network interface registered on the DynDNS registration service

No

dyndns-name

Local host name registered on the DynDNS registration service

No

period

Time between two IP address checks in seconds. Default: 900s (15mn).

No

If you want to use the dynamic registration facility you need:

Your host may have more than one IP address. To identify this IP address you can specify the local name for this IP address (specified in /etc/hosts on Linux/Unix and on \windows\System32\drivers\etc\hosts on Windows) or specify the interface name, for instance ppp0 for a dialup link on Windows. To list the interfaces defined on your system use the ipconfig command or use this Java class.

Token API

The Token API implementation has only one parameter, token-period. When token-period has expired the Token API considers that the frame was lost and asks to the previous PageBoxes on the ring for the frame. By default token-period equals 2000 (2 seconds). token-period must be higher than the highest token-period of the Repositories from which this PageBox deployed archives using the token API.

SSL

The explanation for the SSL setting in PageBox is pretty much the same as for the SSL setting in the Repository.

Principle

The Secure Socket Layer (SSL) has three functions:

  1. Encryption: a man in the middle cannot read the sent archive

  2. Hashing: protection against tampering

  3. A Repository that calls the PageBox Web service checks that the remote server is a valid PageBox server and not a fake server

The PageBox automatically detects if SSL is in place with the following snippet:

String cypher = (String)request.getAttribute("javax.servlet.request.cipher_suite");

if (request.isSecure() && cypher.startsWith("SSL"))

...

Getting started

SSL setting is well described in a Tomcat how-to. Here is a summary. To use SSL you must

In Java key pairs and certificates are stored in keystore files.

For testing you can create the keystore, a key pair and a certificate with the following command:

keytool -genkey -alias tomcat -keyalg RSA

keytool asks many questions. If you want to simplify the subsequent Tomcat configuration step use the default password, which is "changeit" for the keystore and the key. Put down the PageBox host name when keytool asks you to enter your first name and last name. Otherwise, you will encounter "HTTPS hostname wrong error" exception.

The PageBox host name is:

The command above creates the default key if it does not already exist in a file named .keystore in the user's home directory, which is on Win 2K and XP Documents and Settings\username.

Now you can configure Tomcat to use SSL. Define a SSL connector in $TOMCAT_ROOT/conf/server.xml:

<-- Define an SSL HTTP/1.1 Connector on port 8443 -->

<!--

<Connector className="org.apache.catalina.connector.http.HttpConnector"

port="8443" minProcessors="5" maxProcessors="75"

enableLookups="true"

acceptCount="10" debug="0" scheme="https" secure="true">

<Factory className="org.apache.catalina.net.SSLServerSocketFactory"

clientAuth="false" protocol="TLS"/>

</Connector>

-->

If you want to prevent users to access the PageBox without SSL comment the HTTP connector definition.

If you use a non-default keystore specify the keystore path in a keystoreFile attribute of the Factory element. If your keystore or certificate has a password different of changeit specify the password in a keystorePass attribute of the Factory element.

Production concern

Do not use “keytool -genkey -alias repository -keyalg RSA” on a production system. The reason is that this command generates a self-signed certificate, which basically says: “I certify that I am what I pretend to be”.

You need a certificate from a certificate authority. To get this certificate:

  1. Generate a PKCS#10 certificate request with the command keytool -certreq -alias tomcat

  2. Use this certificate request to get a certificate from a Certificate Authority

  3. Import the returned certificate in your keystore with the command keytool -import -file certificate_issued_by_CA -alias tomcat

The simplest solution is to use an Internet Certificate Authority, the most famous being Verisign and Thawte. You can also use InstantSSL. These CAs may grant you free certificates for testing purpose. For a trustable certificate you must pay. It has to be said that in this particular case that charging someone for a certificate is the cheapest way to get evidence that a requestor is who it claims to be: (1) the request knew a credit card number and expiration date (2) the requestor did not complain when it was charged for the service.

Another solution is to run a constellation certificate authority, the most popular commercial products being Netscape Management System and Microsoft Certificate service. The cheapest solution consists in using the CA command of OpenSSL. A cookbook explains how to do that.

On a production environment do not use the default password. If a malicious user can read your keystore and guess its password it can use your private key and your security is compromised.

Repository checking

The Repository may also use SSL. In this case the PageBox checks the certificate presented by the Repository to verify that the requestor is a valid Repository and not a fake server. More precisely the PageBox verifies that the issuer of the certificate presented by the Repository is defined in a special keystore called a trust store.

By default this keystore is a file in the Sun jks format. A system property, javax.net.ssl.trustStore specifies its path and another system property javax.net.ssl.trustStorePassword specifies its password. For convenience and consistency we defined two context parameters in the PageBox web.xml:

Name

System property

Meaning

trust-store

javax.net.ssl.trustStore

Path of the trust store

trust-store-passwd

javax.net.ssl.trustStorePassword

Password of the trust store

Note that these parameters are JVM-wide.

If you do not define javax.net.ssl.trustStore at Tomcat startup nor trust-store in the PageBox web.xml then the implementation will use a $JAVA_HOME /lib/security/jssecacerts trust store if it exists and a $JAVA_HOME /lib/security/cacerts if not. Here $JAVA_HOME is the installation path of the runtime ($JDK_JAVA_HOME/jre).

cacert contains a limited number of trusted root certificates that you can display with the command:

keytool -list -keystore \j2sdk1.4.1\jre\lib\security\cacerts

The use of SSL for the Repository implies the same tasks as for PageBox:

  1. Create a public/private key pair. SSL will use the private key for signature and handshaking encryption.

  2. Create a certificate that certifies that the public key belongs to the Repository. SSL will present the certificate to the PageBox that tries to call the Repository Web service.

  3. Configure the Tomcat hosting the Repository to use SSL with this certificate and private key

In the same way as for the PageBox you can use self-signed certificates for the Tomcat hosts of the Repositories. However because each self-signed certificate has a unique issuer, the certificate itself, you must enter in the trust store the Tomcat certificates of all Repositories to which the PageBox is likely to be subscribed.

In a production environment Repository administrators should query a certificate to a constellation certificate authority. Then the administrator of a constellation PageBox only needs to add the certificate of the certificate authority to the trust store.

In both cases:

  1. The PageBox administrator creates the trust store but if it is happy with the default cacerts

  2. The certificate owner exports the certificate and sends it to the PageBox administrator

  3. The PageBox administrator imports the certificate in the trust store

To create the trust store you can use this command:

keytool -genkey -alias pagebox -keyalg RSA -keystore trustStore

To export a certificate stored in a keystore (typically a self-signed certificate) use this command:

keytool -export -alias tomcat -file pagebox.cer

To import a certificate in the trust store use this command:

keytool -import -v -trustcacerts -alias pageboxi -file pagebox.cer -keystore trustStore

rules.xml

rules.xml allows the PageBox administrator to define the subscriber, the Repositories and the publishers that she trusts and how much she trusts these subscribers, Repositories and publishers. Here is an example of rules.xml [Tomcat/Axis case]:

<rules>

<repositories>

<repository>

<name>https://localhost:8443/Repository/RepoQuery.jws</name>

<allow>copy</allow>

<subscriber>

<name>subscriber</name>

<password>subscriber</password>

</subscriber>

<publishers>

<publisher>

<name>publisher</name>

<allow>install</allow>

<extensions>

<extension>serial</extension>

</extensions>

<resources>

<resource>jdbc</resource>

</resources>

</publisher>

<publisher>

...

</publisher>

</publishers>

<extensions>

<extension>myExtension</extension>

</extensions>

<resources>

<resource>mail</resource>

</resources>

<deployer-class>PageBoxLib.AxisDeployer</deployer-class>

<querier-class>PageBoxLib.AxisQuerier</querier-class>

</repository>

<repository>

...

</repository>

<default>

<allow>none</allow>

<extensions>

<extension>myExtension2</extension>

</extensions>

<deployer-class>PageBoxLib.HTTPDeployer</deployer-class>

<querier-class>PageBoxLib.HTTPQuerier</querier-class>

</default>

</repositories>

<resources>

<resource>

<res-name>jdbc</res-name>

<res-ref-name>jdbc/pageboxa</res-ref-name>

<res-type>javax.sql.DataSource</res-type>

<res-auth>Container</res-auth>

</resource>

<resource>

<res-name>mail</res-name>

<res-ref-name>mail/Session</res-ref-name>

<res-type>javax.mail.Session</res-type>

<res-auth>Container</res-auth>

</resource>

</resources>

<extensions>

<extension>

<ext-name>serial</ext-name>

<ext-class>serialExt.Serial</ext-class>

</extension>

<extension>

<ext-name>myExtension</ext-name>

<ext-class>MyPkg.MyExtension</ext-class>

</extension>

<extension>

<ext-name>myExtension2</ext-name>

<ext-class>MyPkg.MyExtension2</ext-class>

</extension>

</extensions>

<target>C:\java\PageBox1</target>

<root-path>/PageBox1</root-path>

<dbcreate>C:\java\dbcreate.bat</dbcreate>

<dbdrop>C;\java\dbdrop.bat</dbdrop>

<driver>com.mysql.jdbc.Driver</driver>

<url>jdbc:mysql://localhost/</url>

<user>pageboxa</user>

<password>pagebox</password>

<timeout>600</timeout>

</rules>

rules.xml contains four sections:

  1. The root section that describes the target environment

  2. The resources section that describes the resources provided by the target Application server

  3. The extensions section that describes the resources provided by the target Application server

  4. The repositories section that describes the allowed Repositories and granted permissions to use resources and extensions

Root section

The Install.class must implement the following interface:

interface InstallIF {

String install(String archPath, PageBoxAPI pba, Map resources, boolean toUpdate);

String uninstall(String archPath, PageBoxAPI pba, Map resources, boolean toUpdate);

}

Where PageBoxAPI has the following signature:

class PageBoxAPI {

LogIF getLog();

java.sql.Connection getConnection();

ResourceInfo getResource(String name);

ExtensionIF getExtension(String name, String parmClass, Object parm);

String[] getClones();

}

Where

SQL connections are established using the parameters defined in a JDBCinfo object:

class JDBCinfo {

String driver = null;

String url = null;

long timeout;

java.util.Properties props = new java.util.Properties();

}

The Install.class can only write or update files in the archPath directory, use the archive database and write log messages of interest for the PageBox administrator using the log object. We describe the resources usage in the resource section below. For more information read the user guide.

Elements in the root section allow the administrator to set the parameters used by PageBox to invoke the Install.class of the archives.

Element

Meaning

Install.class

target

Target root directory

archPath = target + "/" + archive_name_without_extension

root-path

Root path in the URL

URL = ApplicationServerURL + rootPath + "/" + archive_name_without_extension

driver

JDBC driver

JDBCinfo.driver

url

JDBC url

JDBCinfo.url

timeout

Connection timeout in seconds (default 900 - 15 mn)

JDBCinfo.timeout

user

User ID used to connect to the database

JDBCinfo.props["user"]

password

Password used to connect to the database

JDBCinfo.props["password"]

server

Database server

JDBCinfo.props["server"]

appname

Database application

JDBCinfo.props["application"]

hostname

Database host name

JDBCinfo.props["hostname"]

dbcreate

Path of the database creation script

N/A

dbdrop

Path of the database deletion script

N/A

Starting with version 0.0.7, PageBox manages a database per application. The name of this database is PageBox_working_directory + "_" + Archive_directory. The actual setting depends on the url format:

The PageBox administrator can set scripts called at archive installation and uninstallation, whose paths are dbcreate and dbdrop. These scripts are called with two parameters:

We give four examples of scripts in pagebox.war, dbcreate.bat and dbcreate.sh to create a mysql database and dbdrop.bat and dbdrop.sh to drop a mysql database.

Here is dbcreate.bat (Windows):

E:

cd \mysql\bin

mysql -upageboxa -ppagebox -e "create database %1%;"

Here is dbcreate.sh (Linux, Unix):

# Assume that mysql is on the path of the Tomcat user

mysql -upageboxa -ppagebox -e "create database $1;"

Here is dbdrop.bat (Windows):

E:

cd \mysql\bin

mysql -upageboxa -ppagebox -e "drop database %1%;"

Here is dbdrop.sh (Linux, Unix):

# Assume that mysql is on the path of the Tomcat user

mysql -upageboxa -ppagebox -e "drop database $1;"

dbcreate is primarily designed to create an archive-specific database and dbdrop is primarily designed to drop this archive-specific database. However a PageBox administrator can use them to perform other initialization (dbcreate) and cleanup (dbdrop) tasks. An initialization script can parse an XML file defined with a well-known name in the archive directory. The publisher may use this facility to require archive-specific tasks.

target is also used to define where to inflate the Web archive. Because of that target is a mandatory element. Other elements in the root section are optional.

resources section

The resources section is optional.

Here is an example:

<resources>

<resource>

<res-name>mail</res-name>

<res-ref-name>mail/Session</res-ref-name>

<res-type>javax.mail.Session</res-type>

<res-auth>Container</res-auth>

</resource>

<resource>

<res-name>jdbc</res-name>

<res-ref-name>jdbc/pageboxa</res-ref-name>

<res-type>javax.sql.DataSource</res-type>

<res-auth>Container</res-auth>

</resource>

...

</resources>

The resources section allows the Install.class programmer to update the archive’s web.xml to use the Application server resources.

The resources parameter of the install and uninstall parameters is a Map whose key is the resource name and value is a ResourceInfo object. The ResourceInfo class is defined like this:

class ResourceInfo {

String reference;

String type;

String auth;

}

Where:

Here is how PageBox interprets the resource section to build the resources Map:

rules.xml element

resource Map

res-name

Key

res-ref-name

ResourceInfo.reference

res-type

ResourceInfo.type

res-auth

ResourceInfo.auth

The install class can update web.xml with the following snippet:

ResourceInfo resourceInfo;

...

webXmlOut.println("<resource-ref>");

webXmlOut.println("<res-ref-name>" + resourceInfo.reference + "</res-ref-name>");

webXmlOut.println("<res-type>" + resourceInfo.type + "</res-type>");

webXmlOut.println("<res-auth>" + resourceInfo.auth + "</res-auth>");

webXmlOut.println("</resource-ref>");

...

This is needed to link the Web archive to a resource defined in the Application server configuration. Here is an example. You can add this snippet in the Engine or in the Host element of $TOMCAT_ROOT/conf/server.xml:

<DefaultContext>

<Resource auth="Container" name="jdbc/pageboxa" type="javax.sql.DataSource"/>

<ResourceParams name="jdbc/pageboxa">

<parameter>

<name>factory</name>

<value>org.apache.naming.factory.DbcpDataSourceFactory</value>

</parameter>

<parameter>

<name>user</name>

<value>pageboxa</value>

</parameter>

<parameter>

<name>maxWait</name>

<value>5000</value>

</parameter>

<parameter>

<name>maxActive</name>

<value>4</value>

</parameter>

<parameter>

<name>password</name>

<value>pagebox</value>

</parameter>

<parameter>

<name>url</name>

<value>jdbc:mysql://localhost/pageboxa</value>

</parameter>

<parameter>

<name>driverClassName</name>

<value>com.mysql.jdbc.Driver</value>

</parameter>

<parameter>

<name>maxIdle</name>

<value>2</value>

</parameter>

</ResourceParams>

</DefaultContext>

See the Tomcat documentation for more information.

In the same way the PageBox API allows retrieving resources by name.

For instance the installed archive can use the resource configured by install.class with something like:

PageBoxAPI api = new PageBoxAPI(dir);

ResourceInfo ri = api.getResource("jdbc");

if (ri.type.equals("javax.sql.DataSource")) {

Context initCtx = new InitialContext();

Context envCtx = (Context) initCtx.lookup("java:comp/env");

DataSource ds = (DataSource)envCtx.lookup(ri.reference);

Connection conn = ds.getConnection();

...

conn.close();

}

The PageBox administrators and the archive programmers must use the same resource naming conventions.

When the PageBox administrators choose to provide resource support, they should provide;

extensions section

The extensions section is optional.

Here are the extension elements:

rules.xml element

resource Map

ext-name

Key

ext-class

Extension class name

An extension is a facility provided by the PageBox administrator to allow archives to perform potentially insecure tasks in a controlled manner.

An archive can instantiate an extension with the getExtension method:

ExtensionIF getExtension(String name, String parmClass, Object parm);

Where

When the archive calls the getExtension method the PageBoxAPI creates an object of the associated ext_class type with a constructor whose single parameter is of the parmClass type and contains the parm object.

The extension must implement the ExtensionIF interface defined like this:

interface ExtensionIF {

Object call(Object obj) throws Exception;

}

The archive calls this call method through a wrapper that also implements the ExtensionIF interface.

The Epimetheus example version 0.0.3 and above calls an extension that lists the host serial and parallel ports.

repositories section

The repositories section contains one or many repository elements and a default elements.

A repository element may contain a subscriber and a publishers section.

A publishers section contains one or many publisher elements.

The most important elements are publisher, default and repository, which have an object structure:

A publisher can contains an allow element, an extensions and a resources sections.

A repository and the default can also contain an allow element, an extensions and a resources sections but

publishers section

Each publisher is represented by a publisher element that contains:

Element

Meaning

name

The user name of the publisher who published the archive (the owner)

allow

"install", "copy" or "none".

extensions

Contains extension elements whose value is also defined in an ext-name in the extensions section

resources

Contains resource elements whose value is also defined in a res-name in the resources section

default element

The PageBox default settings are defined in a default element.

Because the default element inherits from the publisher element it may also have an allow element, an extensions and a resources sections with the same meaning as described in the publisher element.

The default element can also contain:

Element

Meaning

unauthenticated

How to deal with requests coming from a unknown Repository. In this case there is no subscriber section and the PageBox has no way to check the Repository credentials. If unauthenticated = true requests are accepted.

deployer-class

Class used to invoke the remote PageBoxes’ service (DeployIF)

querier-class

Class used to invoke the Repository service (RepoQueryIF)

Version 0.0.10 and above are packaged in three flavors to help getting started. We give now the values to setup for JWSDP, Tomcat/Axis and raw HTTP:

Flavor

Tomcat/Axis

JWSDP

Raw HTTP

deployer-class

PageBoxLib. AxisDeployer

PageBoxLib. JWSDPDeployer

PageBoxLib. HTTPDeployer

querier-class

PageBoxLib. AxisQuerier

PageBoxLib. JWSDPQuerier

PageBoxLib. HTTPQuerier

The default mode is JWSDP. The default values are therefore:

repositories section

Each repository is represented by a repository element.

Because a default repository inherits from the publisher element it may also have an allow element, an extensions and a resources sections with the same meaning as described in the publisher element.

A repository element can also contain:

Element

Meaning

name

The URL of the RepoQueryIF service of the Repository

subscriber

See below.

deployer-class

Class used to invoke the remote PageBoxes’ service.

querier-class

Class used to invoke the Repository service.

subscriber section

The subscriber section contains the user name and password of the subscriber allowed to subscribe the PageBox to a Repository. This information is used for two purposes:

  1. When the repository sends a deployment request it provides the name of the subscriber who subscribed the PageBox. If this subscriber is not the same as the subscriber defined in the subscriber section the request is rejected.

  2. In case of relayed deployment, the PageBox can act as a relay for the deployment. In this case it uses the RepoQuery Web service to inform the Repository about the success of the deployments it was responsible for. The PageBox uses the (user, password) to authenticate to the Repository.

The repositories data are used in combination. Therefore their usage is explained in a Security and Permissions topic.

Security

Deploy and Undeploy requests contain:

The diagram below shows how PageBox uses the repositories data.

The PageBox first checks if the Repository that deploys or undeploys is defined in the memory representation of rules.xml. If the Repository is defined the Pagebox checks if the request is issued on behalf of the subscriber specified in rules.xml (not depicted on the diagram). If the request is not issued on behalf of this subcriber the request is rejected. Otherwise the PageBox checks if the archive publisher is defined for this Repository. If it is the case the PageBox uses the allow element of the publisher to setup the deployment right. If the publisher is not defined for this Repository the PageBox uses the allow element of the Repository to setup the deployment right.

If the Repository that deploys or undeploys is not defined in the memory representation of rules.xml the PageBox checks if the unauthenticated element in default is set to true. If it is not the case the request is rejected. Otherwise the PageBox uses the allow element of default to setup the deployment right.

It is also possible to not define the allow element at the publisher or at the Repository level. The PageBox uses the most specific allow.

If the deployment right is "none" the request is rejected and the PageBox returns an error "Not allowed to [un]deploy". If the deployment right equals "copy" the PageBox inflates the archive and calls the Application server deployment. If the deployment right equals "install" the PageBox inflates the archive, runs the dbcreate script, calls the archive Install.class and then the Application server deployment.

The PageBox builds resource and extension sets that contain extensions and resources defined at the default, repository and publisher level. Do not define a resource or an extension at multiple levels.

An archive can only use resources defined in the resource set and extensions defined in the extension set.

Extensions

Install extensions at the same place as pageboxLib.jar:

  1. As a shared library: the recommended and secure way

  2. As a archive library

With the latter method you must include extension archives in WEB-INF/lib of the web archives of all Web applications deployed with PageBox that use the extension. Therefore the deployment takes more time and uses more bandwidth and the Application server uses more memory.

To install an extension archive as a shared library on WSDP, copy the extension archive into $TOMCAT_ROOT/shared/lib.

Sandbox

PageBox for Java version 0.0.7 and above implement a Java 2 security:

Install.class runs with two permissions:

  1. PropertyPermission("*", "read")

  2. FilePermission(archDir + File.separator + "-", "read,write,delete")

Which means that Install.class can read properties and change files in the directory where the archive was inflated.

To use this facility you must:

  1. Install pageboxLib.jar and the extension archives as shared libraries

  2. Customize $WSDL_ROOT/conf/catalina.policy

  3. Start WSDP with security. The security is not setup by default.

catalina.policy

You must restrict default permissions (that allow for instance to write everywhere) and give all permissions to PageBox, PageBoxLib and to extension archives.

We recommend to comment in default permissions (in grant { ... })

permission java.io.FilePermission "-", "read,write,delete";

Your Web applications will still be able to change files in their directories because Web applications are given a read/write/delete FilePermission for files and directories in their document root. If you need to grant file permissions to specific files you can add lines like:

permission java.io.FilePermission "E:/java/pandora/keystore", "read";

Note for Window users:

Use slashes and not backslashes in the file path.

You should also comment in default permissions Runtime permissions such as:

permission java.lang.RuntimePermission "loadLibrary";

permission java.lang.RuntimePermission "queuePrintJob";

You must grant all permissions to PageBox and PageBoxLib (archive stored in $TOMCAT_ROOT/shared/lib):

grant codeBase "file:${catalina.home}/shared/lib/-" {

permission java.security.AllPermission;

};

grant codeBase "file:${catalina.home}/webapps/PageBox/WEB-INF/-" {

permission java.security.AllPermission;

};

Granting permissions to PageBox and PageBoxLib is not an issue because:

You control these archives: you download and install them

You can check and recompile their sources

PageBoxLib actually require the most sensitive permissions:

  1. The permission to create and use a class loader (to instantiate Install.class)

  2. The permission to run scripts (dbcreate and dbdrop)

Without a correct security setting a malicious publisher can break your hosting system or use it to spread viruses. Therefore we recommend setting security when you cannot trust your Repository at 100%. We also recommend checking your security. We give an example in Pandora 0.0.2 made of the CheckSandbox, CheckClassLoader, CheckLoaded, and CheckLoad classes. This example checks that a PageBox hosted application cannot read and write files everywhere, create a class loader, run native code or commands.

Start

Start WSDP with:

%TOMCAT_ROOT%\bin\start.sh -security (Unix, Linux)

$TOMCAT_ROOT/bin/start.bat -security (Windows)

Resource probe

On Windows NT, 2000, XP the resource probe of the default implementation uses JNI and a dll WindowsCPU.dll. You must add this dll directory in the PATH before starting Tomcat.

Customized versions of PageBox may also use shared libraries in their resource probes. In such cases add this shared library directory to the shared library path before starting Tomcat. The shared library path variable is frequently called LD_LIBRARY_PATH. Check the JNI and the Operating System documentation in case of doubt.

Contact:support@pagebox.net
©2002-2004 Alexis Grandemange. Last modified .