kward 2002/12/20 22:13:28
Added: java/scratchpad/src/org/apache/xindice/client/xmldb/xmlrpcssl CollectionImpl.java DatabaseImpl.java HostnameVerifierImpl.java X509TrustManagerImpl.java Log: adding secure XML:DB driver (SSL) Revision Changes Path 1.1 xml-xindice/java/scratchpad/src/org/apache/xindice/client/xmldb/xmlrpcssl/CollectionImpl.java Index: CollectionImpl.java =================================================================== package org.apache.xindice.client.xmldb.xmlrpcssl; /* * The Apache Software License, Version 1.1 * * * Copyright (c) 1999 The Apache Software Foundation. All rights * reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The end-user documentation included with the redistribution, * if any, must include the following acknowledgment: * "This product includes software developed by the * Apache Software Foundation (http://www.apache.org/)." * Alternately, this acknowledgment may appear in the software itself, * if and wherever such third-party acknowledgments normally appear. * * 4. The names "Xindice" and "Apache Software Foundation" must * not be used to endorse or promote products derived from this * software without prior written permission. For written * permission, please contact [EMAIL PROTECTED] * * 5. Products derived from this software may not be called "Apache", * nor may "Apache" appear in their name, without prior written * permission of the Apache Software Foundation. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation and was * originally based on software copyright (c) 1999-2001, The dbXML * Group, L.L.C., http://www.dbxmlgroup.com. For more * information on the Apache Software Foundation, please see * <http://www.apache.org/>. * * $Id: CollectionImpl.java,v 1.1 2002/12/21 06:13:27 kward Exp $ */ import org.apache.xindice.client.xmldb.ResourceSetImpl; import org.apache.xindice.client.xmldb.XindiceCollection; import org.apache.xindice.client.xmldb.resources.XMLResourceImpl; import org.apache.xindice.client.xmldb.xmlrpcssl.X509TrustManagerImpl; import org.apache.xindice.client.xmldb.xmlrpcssl.HostnameVerifierImpl; import org.apache.xindice.core.FaultCodes; import org.apache.xindice.server.rpc.RPCDefaultMessage; import org.apache.xindice.util.SymbolDeserializer; import org.apache.xindice.xml.TextWriter; import org.apache.xmlrpc.XmlRpc; import org.apache.xmlrpc.XmlRpcClient; import org.w3c.dom.*; import org.xml.sax.InputSource; import org.xmldb.api.base.Collection; import org.xmldb.api.base.ErrorCodes; import org.xmldb.api.base.Resource; import org.xmldb.api.base.ResourceSet; import org.xmldb.api.base.XMLDBException; import org.xmldb.api.modules.XMLResource; import java.io.StringReader; import java.net.MalformedURLException; import java.util.Hashtable; import java.util.Vector; import java.security.Security; import javax.xml.parsers.DocumentBuilderFactory; import javax.net.ssl.SSLSocketFactory; import com.sun.net.ssl.KeyManager; import com.sun.net.ssl.SSLContext; import com.sun.net.ssl.HttpsURLConnection; /** * Implementation of XML:DB's <code>Collection</code> interface using * XML-RPC to interact with database server * * @author <a href="mailto:[EMAIL PROTECTED]">James Bates</a> * @author <a href="mailto:[EMAIL PROTECTED]">Kimbro Staken</a> * @author <a href="mailto:[EMAIL PROTECTED]">Kurt Ward</a> */ public class CollectionImpl extends XindiceCollection { /* path to XML-RPC service on database */ private static String XINDICE_SERVICE_LOCATION = "/xindice-1.1b"; /* host and port number of server */ private String hostPort; /* the XML-RPC client stub, connected to server */ private XmlRpcClient client = null; /** * Creates new <code>CollectionImpl</code> instance representing connection * to server collection. * * @param hostPort hostname and port number in <code>host:port</code> format. * Port no is optional, in which case HTTP default is assumed. * @exception org.xmldb.api.base.XMLDBException thrown if a connection could not be established, * because of URL syntax errors, or connection failure, or if no * collection with path <code>collPath</code> could be located. */ public CollectionImpl(String hostPort, String collPath) throws XMLDBException { super(collPath); this.hostPort = hostPort; this.collPath = collPath; String xmlrpcURI = "https://" + hostPort + XINDICE_SERVICE_LOCATION; try { System.out.println("**** XML:DB Driver Info: Initializing SSL keys"); setupSSL(); } catch (Exception e) { throw new XMLDBException(ErrorCodes.VENDOR_ERROR, "SSL client failed to initialize", e); } XmlRpc.setEncoding("UTF8"); XmlRpc.setKeepAlive(true); try { XmlRpc.setDriver("xerces"); } catch (Exception e) { throw new XMLDBException(ErrorCodes.VENDOR_ERROR, "Xerces needed", e); } try { System.out.println("**** XML:DB Driver Info: Using URI: "+xmlrpcURI); client = new XmlRpcClient(xmlrpcURI); /* Just check the collection does actually exist */ Hashtable params = new Hashtable(); params.put(RPCDefaultMessage.COLLECTION, collPath); runRemoteCommand("GetCollectionConfiguration", params); } catch (MalformedURLException e) { client = null; throw new XMLDBException(ErrorCodes.INVALID_URI, e); } catch (Exception e) { client = null; throw new XMLDBException(ErrorCodes.NO_SUCH_COLLECTION, "Collection not found: " + collPath, e); } } /** * Submits a command for RPC to database server * * @param cmdName command name * @param params hashtable containing named parameters to send to server * @return the return value from the server. Type of return value depends on * command. * * @exception java.lang.Exception thrown if XML-RPC reports an exception. */ private Object runRemoteCommand(String cmdName, Hashtable params) throws Exception { params.put("message", cmdName); Vector v = new Vector(); v.add(params); System.out.println("**** XML:DB Driver Info: Running command: "+cmdName); return ((Hashtable) client.execute("run",v)).get(RPCDefaultMessage.RESULT); } /** * Retrieves a <code>Resource</code> from the database. If the * <code>Resource</code> could not be * located a null value will be returned. * * @param id the unique id for the requested resource. * @return The retrieved <code>Resource</code> instance. * @exception org.xmldb.api.base.XMLDBException with expected error codes.<br /> * <code>ErrorCodes.VENDOR_ERROR</code> for any vendor * specific errors that occur.<br /> * <code>ErrorCodes.COLLECTION_CLOSED</code> if the <code>close</code> * method has been called on the <code>Collection</code><br /> */ public Resource getResource(String id) throws XMLDBException { checkOpen(); try { Hashtable params = new Hashtable(); params.put(RPCDefaultMessage.COLLECTION, collPath); params.put(RPCDefaultMessage.NAME, id); params.put(RPCDefaultMessage.COMPRESSED, "true"); Object result = runRemoteCommand("GetDocument", params); /* * If we get a Hashtable back then the result is compressed. */ if ( result instanceof Hashtable ) { Hashtable compressed = (Hashtable) result; SymbolDeserializer symbolDeserial = new SymbolDeserializer(); return new XMLResourceImpl(id, id, this, symbolDeserial.getSymbols(compressed), (byte []) compressed.get("document")); } else { return new XMLResourceImpl(id, (String) result, this); } } catch (Exception e) { return null; } } /** * Returns the number of resources currently stored in this collection or 0 * if the collection is empty. * * @return the number of resource in the collection. * @exception org.xmldb.api.base.XMLDBException with expected error codes.<br /> * <code>ErrorCodes.VENDOR_ERROR</code> for any vendor * specific errors that occur.<br /> * <code>ErrorCodes.COLLECTION_CLOSED</code> if the <code>close</code> * method has been called on the <code>Collection</code><br /> */ public int getResourceCount() throws XMLDBException { checkOpen(); try { Hashtable params = new Hashtable(); params.put(RPCDefaultMessage.COLLECTION, collPath); return ((Integer) runRemoteCommand( "GetDocumentCount", params)).intValue(); } catch (Exception e) { throw new XMLDBException(ErrorCodes.UNKNOWN_ERROR, e); } } /** * Stores the provided resource into the database. If the resource does not * already exist it will be created. If it does already exist it will be * updated. * * @param res the resource to store in the database. * @exception org.xmldb.api.base.XMLDBException with expected error codes.<br /> * <code>ErrorCodes.VENDOR_ERROR</code> for any vendor * specific errors that occur.<br /> * <code>ErrorCodes.INVALID_RESOURCE</code> if the <code>Resource</code> is * not valid. * <code>ErrorCodes.COLLECTION_CLOSED</code> if the <code>close</code> * method has been called on the <code>Collection</code><br /> */ public void storeResource(Resource res) throws XMLDBException { if (!(res instanceof XMLResource)) { throw new XMLDBException(ErrorCodes.INVALID_RESOURCE, "Only XML resources supported"); } if (res.getContent() == null) { throw new XMLDBException(ErrorCodes.INVALID_RESOURCE, "no resource data"); } checkOpen(); try { Hashtable params = new Hashtable(); params.put(RPCDefaultMessage.COLLECTION, collPath); params.put(RPCDefaultMessage.NAME, res.getId()); params.put(RPCDefaultMessage.DOCUMENT, res.getContent()); String name = (String) runRemoteCommand("InsertDocument", params); ((XMLResourceImpl) res).setId(name); } catch (Exception e) { throw new XMLDBException(ErrorCodes.UNKNOWN_ERROR, e); } } /* see superclass for documentation */ public boolean isOpen() { return (client != null); } /* see superclass for documentation */ public String getURI() { return "xmldb:" + DatabaseImpl.DRIVER_NAME + "://" + hostPort + collPath; } /** * Returns a <code>Collection</code> instance for the requested child collection * if it exists. * * @param name the name of the child collection to retrieve. * @return the requested child collection or null if it couldn't be found. * @exception org.xmldb.api.base.XMLDBException with expected error codes.<br /> * <code>ErrorCodes.VENDOR_ERROR</code> for any vendor * specific errors that occur.<br /> * <code>ErrorCodes.COLLECTION_CLOSED</code> if the <code>close</code> * method has been called on the <code>Collection</code><br /> */ public Collection getChildCollection(String name) throws XMLDBException { if (name.indexOf('/') != -1) { throw new XMLDBException(ErrorCodes.INVALID_COLLECTION); } try { return new CollectionImpl(hostPort, collPath + "/" + name); } catch (XMLDBException e) { if (e.errorCode == ErrorCodes.NO_SUCH_COLLECTION) { // per getChildCollection contract, return null if not found return null; } throw e; } } /** * Creates a new unique ID within the context of the <code>Collection</code> * * @return the created id as a string. * @exception org.xmldb.api.base.XMLDBException with expected error codes.<br /> * <code>ErrorCodes.VENDOR_ERROR</code> for any vendor * specific errors that occur.<br /> * <code>ErrorCodes.COLLECTION_CLOSED</code> if the <code>close</code> * method has been called on the <code>Collection</code><br /> */ public String createId() throws XMLDBException { checkOpen(); try { Hashtable params = new Hashtable(); params.put(RPCDefaultMessage.COLLECTION, collPath); return (String) runRemoteCommand("CreateNewOID", params); } catch (Exception e) { throw new XMLDBException(ErrorCodes.UNKNOWN_ERROR, e); } } /** * Releases all resources consumed by the <code>Collection</code>. * The <code>close</code> method must * always be called when use of a <code>Collection</code> is complete. It is * not safe to use a <code>Collection</code> after the <code>close</code> * method has been called. * * @exception org.xmldb.api.base.XMLDBException with expected error codes.<br /> * <code>ErrorCodes.VENDOR_ERROR</code> for any vendor * specific errors that occur.<br /> */ public void close() throws XMLDBException { client = null; } /** * Returns the parent collection for this collection or null if no parent * collection exists. * * @return the parent <code>Collection</code> instance. * @exception org.xmldb.api.base.XMLDBException with expected error codes.<br /> * <code>ErrorCodes.VENDOR_ERROR</code> for any vendor * specific errors that occur.<br /> * <code>ErrorCodes.COLLECTION_CLOSED</code> if the <code>close</code> * method has been called on the <code>Collection</code><br /> */ public Collection getParentCollection() throws XMLDBException { // If there's only one slash then it's the root. if (collPath.lastIndexOf("/") == 0) { return null; } try { return new CollectionImpl(hostPort, collPath.substring(0, collPath.lastIndexOf('/'))); } catch (XMLDBException e) { if (e.errorCode == ErrorCodes.NO_SUCH_COLLECTION) { // per getParentCollection contract, return null if no parent return null; } throw e; } } /** * Removes the <code>Resource</code> from the database. * * @param res the resource to remove. * @exception org.xmldb.api.base.XMLDBException with expected error codes.<br /> * <code>ErrorCodes.VENDOR_ERROR</code> for any vendor * specific errors that occur.<br /> * <code>ErrorCodes.INVALID_RESOURCE</code> if the <code>Resource</code> is * not valid.<br /> * <code>ErrorCodes.NO_SUCH_RESOURCE</code> if the <code>Resource</code> is * not known to this <code>Collection</code>. * <code>ErrorCodes.COLLECTION_CLOSED</code> if the <code>close</code> * method has been called on the <code>Collection</code><br /> */ public void removeResource(Resource res) throws XMLDBException { if (!(res instanceof XMLResource)) { throw new XMLDBException(ErrorCodes.INVALID_RESOURCE, "Only XML resources supported"); } if (res.getId() == null) { throw new XMLDBException(ErrorCodes.VENDOR_ERROR, "This resource is a query result and can " + "not be removed from the database."); } checkOpen(); try { Hashtable params = new Hashtable(); params.put(RPCDefaultMessage.COLLECTION, collPath); params.put(RPCDefaultMessage.NAME, res.getId()); runRemoteCommand("RemoveDocument", params); } catch (Exception e) { throw new XMLDBException(ErrorCodes.NO_SUCH_RESOURCE, e); } } /** * Returns a list of collection names naming all child collections * of the current collection. If no child collections exist an empty list is * returned. * * @return an array containing collection names for all child * collections. * @exception org.xmldb.api.base.XMLDBException with expected error codes.<br /> * <code>ErrorCodes.VENDOR_ERROR</code> for any vendor * specific errors that occur.<br /> * <code>ErrorCodes.COLLECTION_CLOSED</code> if the <code>close</code> * method has been called on the <code>Collection</code><br /> */ public String[] listChildCollections() throws XMLDBException { checkOpen(); try { Hashtable params = new Hashtable(); params.put(RPCDefaultMessage.COLLECTION, collPath); Vector list = (Vector) runRemoteCommand("ListCollections", params); return (String[]) list.toArray(new String[list.size()]); } catch (Exception e) { throw new XMLDBException(ErrorCodes.UNKNOWN_ERROR, e); } } /** * Returns the number of child collections under this * <code>Collection</code> or 0 if no child collections exist. * * @return the number of child collections. * @exception org.xmldb.api.base.XMLDBException with expected error codes.<br /> * <code>ErrorCodes.VENDOR_ERROR</code> for any vendor * specific errors that occur.<br /> * <code>ErrorCodes.COLLECTION_CLOSED</code> if the <code>close</code> * method has been called on the <code>Collection</code><br /> */ public int getChildCollectionCount() throws XMLDBException { checkOpen(); try { Hashtable params = new Hashtable(); params.put(RPCDefaultMessage.COLLECTION, collPath); Integer result = (Integer) runRemoteCommand("GetCollectionCount", params); return result.intValue(); } catch (Exception e) { throw new XMLDBException(ErrorCodes.UNKNOWN_ERROR, e); } } /** * Returns a list of the ids for all resources stored in the collection. * * @return a string array containing the names for all * <code>Resource</code>s in the collection. * @exception org.xmldb.api.base.XMLDBException with expected error codes.<br /> * <code>ErrorCodes.VENDOR_ERROR</code> for any vendor * specific errors that occur.<br /> * <code>ErrorCodes.COLLECTION_CLOSED</code> if the <code>close</code> * method has been called on the <code>Collection</code><br /> */ public String[] listResources() throws XMLDBException { checkOpen(); try { Hashtable params = new Hashtable(); params.put(RPCDefaultMessage.COLLECTION, collPath); Vector list = (Vector) runRemoteCommand("ListDocuments", params); return (String[]) list.toArray(new String[list.size()]); } catch (Exception e) { throw new XMLDBException(ErrorCodes.UNKNOWN_ERROR, e); } } /* see superclass for documentation */ public ResourceSet query(String name, String queryLang, String query, Hashtable nsMap) throws XMLDBException { checkOpen(); try { Hashtable params = new Hashtable(); params.put(RPCDefaultMessage.COLLECTION, collPath); params.put(RPCDefaultMessage.TYPE, queryLang); params.put(RPCDefaultMessage.NAMESPACES, nsMap); params.put(RPCDefaultMessage.QUERY, query); if (name != null) { params.put(RPCDefaultMessage.NAME, name); } String result = (String) runRemoteCommand("Query", params); DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); dbf.setNamespaceAware(true); Document resultDoc = dbf.newDocumentBuilder().parse( new InputSource(new StringReader(result))); NodeList nodes = resultDoc.getDocumentElement().getChildNodes(); ResourceSetImpl rs = new ResourceSetImpl(this, null); for (int i = 0; i < nodes.getLength(); i++) { Node n = nodes.item(i); String documentId = ((Element) n).getAttributeNS( QUERY_NS, "key"); XMLResourceImpl resource = new XMLResourceImpl(null, documentId, this, TextWriter.toString(n)); rs.addResource(resource); } return rs; } catch (Exception e) { throw FaultCodes.createXMLDBException(FaultCodes.QRY_PROCESSING_ERROR, "Query error", e); } } /* see superclass for documentation */ public Collection createCollection(String childName) throws XMLDBException { checkOpen(); try { Hashtable params = new Hashtable(); params.put(RPCDefaultMessage.COLLECTION, collPath); params.put(RPCDefaultMessage.NAME, childName); runRemoteCommand("CreateCollection", params); return getChildCollection(childName); } catch (Exception e) { throw new XMLDBException(ErrorCodes.INVALID_COLLECTION, "Cannot create child collection", e); } } /* see superclass for documentation */ public Collection createCollection(String name, Document configuration) throws XMLDBException { checkOpen(); try { Hashtable params = new Hashtable(); params.put(RPCDefaultMessage.COLLECTION, collPath); params.put(RPCDefaultMessage.NAME, name); params.put(RPCDefaultMessage.CONFIGURATION, TextWriter.toString( configuration ) ); runRemoteCommand("CreateCollection", params); return getChildCollection(name); } catch (Exception e) { throw new XMLDBException(ErrorCodes.INVALID_COLLECTION, "Cannot create child collection", e); } } /* see superclass for documentation */ public void removeCollection(String childName) throws XMLDBException { checkOpen(); try { Hashtable params = new Hashtable(); params.put(RPCDefaultMessage.COLLECTION, collPath); params.put(RPCDefaultMessage.NAME, childName); runRemoteCommand("RemoveCollection", params); } catch (Exception e) { throw new XMLDBException(ErrorCodes.INVALID_COLLECTION, "Cannot remove child collection", e); } } /* see superclass for documentation */ public String[] listIndexers() throws XMLDBException { checkOpen(); try { Hashtable params = new Hashtable(); params.put(RPCDefaultMessage.COLLECTION, collPath); Vector list = (Vector) runRemoteCommand("ListIndexers", params); return (String[]) list.toArray(new String[list.size()]); } catch (Exception e) { throw FaultCodes.createXMLDBException(e); } } /* see superclass for documentation */ public void createIndexer(Document configuration) throws XMLDBException { checkOpen(); try { Hashtable params = new Hashtable(); params.put(RPCDefaultMessage.COLLECTION, collPath); params.put(RPCDefaultMessage.CONFIGURATION, TextWriter.toString( configuration ) ); runRemoteCommand("CreateIndexer", params); } catch (Exception e) { throw FaultCodes.createXMLDBException(e); } } /* see superclass for documentation */ public void dropIndexer(String name) throws XMLDBException { checkOpen(); try { Hashtable params = new Hashtable(); params.put(RPCDefaultMessage.COLLECTION, collPath); params.put(RPCDefaultMessage.NAME, name); runRemoteCommand("RemoveIndexer", params); } catch (Exception e) { throw FaultCodes.createXMLDBException(e); } } /* see superclass for documentation */ public void shutdown() throws XMLDBException { checkOpen(); try { Hashtable params = new Hashtable(); runRemoteCommand("Shutdown", params); } catch (Exception e) { throw FaultCodes.createXMLDBException(e); } } private static void setupSSL() throws Exception { //set up system properties System.setProperty("java.protocol.handler.pkgs", "com.sun.net.ssl.internal.www.protocol"); System.setProperty("com.sun.net.ssl.dhKeyExchangeFix", "true"); Security.addProvider(new com.sun.net.ssl.internal.ssl.Provider()); X509TrustManagerImpl tm = new X509TrustManagerImpl(); KeyManager[] km = null; X509TrustManagerImpl[] tma = { tm }; SSLContext sc = SSLContext.getInstance( "SSL" ); sc.init(km,tma,new java.security.SecureRandom()); SSLSocketFactory sf1 = sc.getSocketFactory(); HttpsURLConnection.setDefaultSSLSocketFactory( sf1 ); //Added to allow sites with different names then are on the certificate //completely optional HttpsURLConnection.setDefaultHostnameVerifier( new HostnameVerifierImpl() ); } } 1.1 xml-xindice/java/scratchpad/src/org/apache/xindice/client/xmldb/xmlrpcssl/DatabaseImpl.java Index: DatabaseImpl.java =================================================================== package org.apache.xindice.client.xmldb.xmlrpcssl; /* * The Apache Software License, Version 1.1 * * * Copyright (c) 1999 The Apache Software Foundation. All rights * reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The end-user documentation included with the redistribution, * if any, must include the following acknowledgment: * "This product includes software developed by the * Apache Software Foundation (http://www.apache.org/)." * Alternately, this acknowledgment may appear in the software itself, * if and wherever such third-party acknowledgments normally appear. * * 4. The names "Xindice" and "Apache Software Foundation" must * not be used to endorse or promote products derived from this * software without prior written permission. For written * permission, please contact [EMAIL PROTECTED] * * 5. Products derived from this software may not be called "Apache", * nor may "Apache" appear in their name, without prior written * permission of the Apache Software Foundation. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation and was * originally based on software copyright (c) 1999-2001, The dbXML * Group, L.L.C., http://www.dbxmlgroup.com. For more * information on the Apache Software Foundation, please see * <http://www.apache.org/>. * * $Id: DatabaseImpl.java,v 1.1 2002/12/21 06:13:27 kward Exp $ */ import org.apache.xindice.client.xmldb.CommonConfigurable; import org.apache.xindice.client.xmldb.xmlrpcssl.CollectionImpl; import org.xmldb.api.base.Collection; import org.xmldb.api.base.Database; import org.xmldb.api.base.ErrorCodes; import org.xmldb.api.base.XMLDBException; /** * implements XML:DB's <code>Database</code> interface using XML-RPC to * communicate with the Xindice server. * * Note this class is a database <em>driver</em>, and one class of this database * could be used to connect to <em>many</em> different databases. * * @author <a href="mailto:[EMAIL PROTECTED]">James Bates</a> * @author <a href="mailto:[EMAIL PROTECTED]">Kurt Ward</a> */ public class DatabaseImpl extends CommonConfigurable implements Database { /* prefix used to denote XML:DB URI's that should use this driver */ static String DRIVER_NAME = "xindice-ssl"; /* XML:DB conformance level of this driver */ private String CONFORMANCE_LEVEL = "0"; /** * Determines whether this <code>Database</code> implementation can handle * the URI. It should return true if the Database instance knows how to * handle the URI and false otherwise. * * @param uri the URI to check for. * @return true if the URI can be handled, false otherwise. * @exception org.xmldb.api.base.XMLDBException with expected error codes.<br /> * <code>ErrorCodes.VENDOR_ERROR</code> for any vendor * specific errors that occur.<br /> * <code>ErrroCodes.INVALID_URI</code> If the URI is not in a valid format. <br /> */ public boolean acceptsURI(String uri) throws XMLDBException { return ((uri != null) && uri.startsWith(getName() + "://")); } /** * Retrieves a <code>Collection</code> instance based on the URI provided * in the <code>uri</code> parameter. The format of the URI is defined in the * documentation for DatabaseManager.getCollection().<p/> * * Authentication is handled via username and password however it is not * required that the database support authentication. Databases that do not * support authentication MUST ignore the * <code>username</code> and <code>password</code> if those provided are not * null. * * @param uri the URI to use to locate the collection. * @param password The password to use for authentication to the database or * null if the database does not support authentication. * @return A <code>Collection</code> instance for the requested collection or * null if the collection could not be found. * @return The <code>Collection</code> instance * @exception org.xmldb.api.base.XMLDBException with expected error codes.<br /> * <code>ErrorCodes.VENDOR_ERROR</code> for any vendor * specific errors that occur.<br /> * <code>ErrroCodes.INVALID_URI</code> If the URI is not in a valid format. <br /> * <code>ErrroCodes.PERMISSION_DENIED</code> If the <code>username</code> * and <code>password</code> were not accepted by the database. */ public Collection getCollection(String uri, String userName, String password) throws XMLDBException { /* TODO: introduce authentication some day */ if (!acceptsURI(uri)) { throw new XMLDBException(ErrorCodes.INVALID_URI); } /* Chop off driver prefix, and '://' */ uri = uri.substring(getName().length() + 3); /* Extract host name & port, if present */ int firstSlash = uri.indexOf('/'); if (firstSlash == -1) { throw new XMLDBException(ErrorCodes.INVALID_URI); } String hostPort = uri.substring(0, firstSlash); String collPath = uri.substring(firstSlash); /* Absent host defaults to localhost and standard Xindice HTTP port */ if (hostPort.equals("")) { hostPort = "127.0.0.1:8443"; } try { return new CollectionImpl(hostPort, collPath); } catch(XMLDBException e) { if(e.errorCode == ErrorCodes.NO_SUCH_COLLECTION) { // per getCollection contract, return null if not found return null; } throw e; } } /** * Returns the prefix used in XML:DB to denote URI's that this driver can * handle. * * @return the prefix driver name * @exception org.xmldb.api.base.XMLDBException with expected error codes.<br /> * <code>ErrorCodes.VENDOR_ERROR</code> for any vendor * specific errors that occur.<br /> */ public String getName() throws XMLDBException { return DRIVER_NAME; } /** * Returns the XML:DB API Conformance level for the implementation. This can * be used by client programs to determine what functionality is available to * them. * * @return the XML:DB API conformance level for this implementation. * @exception org.xmldb.api.base.XMLDBException with expected error codes.<br /> * <code>ErrorCodes.VENDOR_ERROR</code> for any vendor * specific errors that occur.<br /> */ public String getConformanceLevel() throws XMLDBException { return CONFORMANCE_LEVEL; } } 1.1 xml-xindice/java/scratchpad/src/org/apache/xindice/client/xmldb/xmlrpcssl/HostnameVerifierImpl.java Index: HostnameVerifierImpl.java =================================================================== package org.apache.xindice.client.xmldb.xmlrpcssl; /* * The Apache Software License, Version 1.1 * * * Copyright (c) 1999 The Apache Software Foundation. All rights * reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The end-user documentation included with the redistribution, * if any, must include the following acknowledgment: * "This product includes software developed by the * Apache Software Foundation (http://www.apache.org/)." * Alternately, this acknowledgment may appear in the software itself, * if and wherever such third-party acknowledgments normally appear. * * 4. The names "Xindice" and "Apache Software Foundation" must * not be used to endorse or promote products derived from this * software without prior written permission. For written * permission, please contact [EMAIL PROTECTED] * * 5. Products derived from this software may not be called "Apache", * nor may "Apache" appear in their name, without prior written * permission of the Apache Software Foundation. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation and was * originally based on software copyright (c) 1999-2001, The dbXML * Group, L.L.C., http://www.dbxmlgroup.com. For more * information on the Apache Software Foundation, please see * <http://www.apache.org/>. * * $Id: HostnameVerifierImpl.java,v 1.1 2002/12/21 06:13:27 kward Exp $ */ import com.sun.net.ssl.HostnameVerifier; import java.net.InetAddress; public class HostnameVerifierImpl implements HostnameVerifier { public boolean verify(String urlHostname, String certHostname) { try { InetAddress iaU = InetAddress.getByName( urlHostname ); InetAddress iaC = InetAddress.getByName( certHostname ); return iaU.equals(iaC); } catch (Exception e) { return false; } } } 1.1 xml-xindice/java/scratchpad/src/org/apache/xindice/client/xmldb/xmlrpcssl/X509TrustManagerImpl.java Index: X509TrustManagerImpl.java =================================================================== package org.apache.xindice.client.xmldb.xmlrpcssl; /* * The Apache Software License, Version 1.1 * * * Copyright (c) 1999 The Apache Software Foundation. All rights * reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The end-user documentation included with the redistribution, * if any, must include the following acknowledgment: * "This product includes software developed by the * Apache Software Foundation (http://www.apache.org/)." * Alternately, this acknowledgment may appear in the software itself, * if and wherever such third-party acknowledgments normally appear. * * 4. The names "Xindice" and "Apache Software Foundation" must * not be used to endorse or promote products derived from this * software without prior written permission. For written * permission, please contact [EMAIL PROTECTED] * * 5. Products derived from this software may not be called "Apache", * nor may "Apache" appear in their name, without prior written * permission of the Apache Software Foundation. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation and was * originally based on software copyright (c) 1999-2001, The dbXML * Group, L.L.C., http://www.dbxmlgroup.com. For more * information on the Apache Software Foundation, please see * <http://www.apache.org/>. * * $Id: X509TrustManagerImpl.java,v 1.1 2002/12/21 06:13:27 kward Exp $ */ import com.sun.net.ssl.X509TrustManager; public class X509TrustManagerImpl implements X509TrustManager { public boolean isClientTrusted( java.security.cert.X509Certificate[] chain ) { return true; } public boolean isServerTrusted( java.security.cert.X509Certificate[] chain ) { return true; } public java.security.cert.X509Certificate[] getAcceptedIssuers() { return null; } }