PageBox |
|
|
|
|
|
Presentation | Install | User guide | Developer guide | Programming | Port | Repository | PageBox | Release notes |
PageBox for Java installation
This page aims to answer three questions:
Where to find PageBox?
How to install and configure PageBox?
How to diagnose PageBox problems?
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.
Web archive (binaries) | |
Sources | |
JavaDoc |
PageBox is made of two parts:
A shared library used by the PageBox Web archive and by the installed (PageBox-enabled) applications.
The PageBox Web archive that handles the deployment requests and displays the administration forms
Library binaries | |
Library sources | |
Library documentation | |
Web archive binaries | |
Web archive sources | |
Web archive JavaDoc | |
Generic installation class |
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.
Web archive (binaries) | |
Sources | |
JavaDoc |
PageBox is made of two parts:
A shared library used by the PageBox Web archive and by the installed (PageBox-enabled) applications.
The PageBox Web archive that handles the deployment requests and displays the administration forms
Library binaries | |
Library sources | |
Library documentation | |
Web archive binaries | |
Web archive sources | |
Web archive JavaDoc | |
Generic installation class |
Web archive (binaries) | |
Sources | |
JavaDoc |
PageBox is made of two parts:
A shared library used by the PageBox Web archive and by the installed (PageBox-enabled) applications.
The PageBox Web archive that handles the deployment requests and displays the administration forms
Library binaries | |
Library sources | |
Library documentation | |
Web archive binaries | |
Web archive sources | |
Web archive JavaDoc | |
Generic installation class |
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.
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 | |
Source |
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.
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.
Inflate the Tomcat tar.
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.
Inflate the Xalan tar. We call the Xalan installation directory $XALAN_ROOT.
Copy xalan.jar from $XALAN_ROOT/bin into $TOMCAT_ROOT/common/endorsed.
The installation consists of:
Setting the Repository WEB-INF
Setting the WSDP security
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 number of PageBoxes
How homogeneous is the PageBox network. If some PageBoxes have a much slower link than others then the relaytime should be higher
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
Retries deployments failed for instance because the target PageBox was not running
Handles the relay management as described above
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>.
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:
deployer-class is the class used to call the Deploy Web service of PageBoxes. This class must implement the DeployIF interface of the PageBox Web service.
RepoQuery-ws represents the service access point for invoking the RepoQueryImpl class. With HTTP protocols this service access point is the Web service URL.
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:
deployer-class: Repository.JWSDPDeployer
RepoQuery-ws: /repoquery
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 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 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 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
The Secure Socket Layer (SSL) has three functions:
Encryption: a man in the middle cannot read the sent archive
Hashing: protection against tampering
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")) ... |
SSL setting is well described in a Tomcat how-to. Here is a summary. To use SSL you must
Create a public/private key pair. SSL will use the private key for signature and handshaking encryption.
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.
Configure Tomcat to use SSL with this certificate and private key
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 DNS name (dyndns-host) if DynDns parameters (see below) were set up and if the dynamic DNS registration has succeeded
Otherwise the local host name as defined in dyndns-name if it is setup
Otherwise the host name retrieved by the Repository with request.getServerName()
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.
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:
Generate a PKCS#10 certificate request with the command keytool -certreq -alias tomcat
Use this certificate request to get a certificate from a Certificate Authority
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.
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:
Create a public/private key pair. SSL will use the private key for signature and handshaking encryption.
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.
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:
The Repository administrator creates the trust store but if it is happy with the default cacerts
The certificate owner exports the certificate and sends it to the Repository administrator
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 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:
An account on a dynamic DNS registration service
To specify the URL of this registration service and the account user and password
To specify the fully qualified DNS name you want to give to your Repository host
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.
Starting with PageBox for Java version 0.0.7 the Repository is tested with Java 2 security.
To use this facility you must:
Customize $TOMCAT_ROOT/conf/catalina.policy
Start the servlet container with security. The security is not setup by default.
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 WSDP with:
%TOMCAT_ROOT%\bin\start.sh -security (Unix, Linux) $TOMCAT_ROOT/bin/start.bat -security (Windows) |
The installation consists of:
Installing the PageBox library
Installing the PageBox and setting its web.xml
Setting rules.xml
Setting the PageBox security
Setting the archive sandbox
There are two ways to use the PageBox library:
As a shared library: the recommended (and, starting in version 0.0.7, secure) way
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.
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.
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 PageBox administrator to display installed archives with update
The PageBox administrator to display the log with audit
The PageBox repository to deploy archives
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 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.
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.
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.
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:
An account on a dynamic DNS registration service
To specify the URL of this registration service and the account user and password
To specify the fully qualified DNS name you want to give to your PageBox host
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.
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.
The explanation for the SSL setting in PageBox is pretty much the same as for the SSL setting in the Repository.
The Secure Socket Layer (SSL) has three functions:
Encryption: a man in the middle cannot read the sent archive
Hashing: protection against tampering
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")) ... |
SSL setting is well described in a Tomcat how-to. Here is a summary. To use SSL you must
Create a public/private key pair. SSL will use the private key for signature and handshaking encryption.
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.
Configure Tomcat to use SSL with this certificate and private key
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 DNS name (dyndns-host) if DynDns parameters (see below) were set up and if the dynamic DNS registration has succeeded
Otherwise the local host name as defined in dyndns-name if it is setup
Otherwise the host name retrieved by the Repository with request.getServerName()
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.
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:
Generate a PKCS#10 certificate request with the command keytool -certreq -alias tomcat
Use this certificate request to get a certificate from a Certificate Authority
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.
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:
Create a public/private key pair. SSL will use the private key for signature and handshaking encryption.
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.
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:
The PageBox administrator creates the trust store but if it is happy with the default cacerts
The certificate owner exports the certificate and sends it to the PageBox administrator
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 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:
The root section that describes the target environment
The resources section that describes the resources provided by the target Application server
The extensions section that describes the resources provided by the target Application server
The repositories section that describes the allowed Repositories and granted permissions to use resources and extensions
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
getLog returns a logging object allowing writing on the PageBox log
getResource returns data about a named resource
getExtension returns an extension class that an archive can use to perform potentially insecure tasks. This method is described in more details in the extensions section.
getClones returns the URLs of the other instances of the Web archive installed from the same Repository
getConnection returns an SQL connection from a PageBox connection pool
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:
If the url ends with a "/" like in jdbc:mysql://localhost/ then PageBox adds the database name to the url
Otherwise PageBox sets a db property: JDBCinfo.props["db"] = database name
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:
Database name
Archive directory
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.
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:
reference is the JNDI name of the resource.
type is the interface implemented by the resource.
auth relates to authorization. auth indicates whether the application component code performs resource signon programmatically or whether the container signs onto the resource based on the principle mapping information supplied by the deployer. See the Servlet specification for more information.
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;
A default JDBC resource called jdbc, using when possible a javax.sql.DataSource type
A optional JavaMail resource called mail using when possible a javax.mail.Session type
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
name is the extension name, defined by an ext-name element of rules.xml
parmClass is the name of the parameter class
parm is the creation parameter
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.
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
A repository can contain a name, a deployer-class and a querier-class elements and a subscriber section
The default can contain an unauthenticated, a deployer-class and a querier-class elements
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 |
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:
deployer-class: PageBoxLib.JWSDPDeployer
querier-class: PageBoxLib.JWSDPQuerier
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. |
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:
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.
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.
Deploy and Undeploy requests contain:
The user name of the subscriber who subscribed the PageBox, the "subscriber" in short
The user name of the publisher who published the archive, the "publisher" in short
The URL of the repository’s RepoQuery web service, the "repository" in short
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.
Install extensions at the same place as pageboxLib.jar:
As a shared library: the recommended and secure way
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.
PageBox for Java version 0.0.7 and above implement a Java 2 security:
Install.class runs with two permissions:
PropertyPermission("*", "read")
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:
Install pageboxLib.jar and the extension archives as shared libraries
Customize $WSDL_ROOT/conf/catalina.policy
Start WSDP with security. The security is not setup by default.
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:
The permission to create and use a class loader (to instantiate Install.class)
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 WSDP with:
%TOMCAT_ROOT%\bin\start.sh -security (Unix, Linux) $TOMCAT_ROOT/bin/start.bat -security (Windows) |
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
.