Return-Path: X-Original-To: apmail-directory-commits-archive@www.apache.org Delivered-To: apmail-directory-commits-archive@www.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id 28D8110877 for ; Sat, 10 Jan 2015 13:30:46 +0000 (UTC) Received: (qmail 98272 invoked by uid 500); 10 Jan 2015 13:30:47 -0000 Delivered-To: apmail-directory-commits-archive@directory.apache.org Received: (qmail 98160 invoked by uid 500); 10 Jan 2015 13:30:47 -0000 Mailing-List: contact commits-help@directory.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@directory.apache.org Delivered-To: mailing list commits@directory.apache.org Received: (qmail 96923 invoked by uid 99); 10 Jan 2015 13:30:46 -0000 Received: from tyr.zones.apache.org (HELO tyr.zones.apache.org) (140.211.11.114) by apache.org (qpsmtpd/0.29) with ESMTP; Sat, 10 Jan 2015 13:30:46 +0000 Received: by tyr.zones.apache.org (Postfix, from userid 65534) id 652559A79F8; Sat, 10 Jan 2015 13:30:46 +0000 (UTC) Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: drankye@apache.org To: commits@directory.apache.org Date: Sat, 10 Jan 2015 13:31:05 -0000 Message-Id: <176c1190ccc7409d8787280e0933efb2@git.apache.org> In-Reply-To: <3c7944fea3f94b338994a3a2caed8ef3@git.apache.org> References: <3c7944fea3f94b338994a3a2caed8ef3@git.apache.org> X-Mailer: ASF-Git Admin Mailer Subject: [21/42] directory-kerberos git commit: Initially import Haox codebase (https://github.com/drankye/haox) http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/23c1fd12/3rdparty/not-yet-commons-ssl/src/main/java/org/apache/commons/ssl/SSLSocketWrapper.java ---------------------------------------------------------------------- diff --git a/3rdparty/not-yet-commons-ssl/src/main/java/org/apache/commons/ssl/SSLSocketWrapper.java b/3rdparty/not-yet-commons-ssl/src/main/java/org/apache/commons/ssl/SSLSocketWrapper.java new file mode 100644 index 0000000..4abeb11 --- /dev/null +++ b/3rdparty/not-yet-commons-ssl/src/main/java/org/apache/commons/ssl/SSLSocketWrapper.java @@ -0,0 +1,356 @@ +/* + * $HeadURL: http://juliusdavies.ca/svn/not-yet-commons-ssl/tags/commons-ssl-0.3.16/src/java/org/apache/commons/ssl/SSLSocketWrapper.java $ + * $Revision: 155 $ + * $Date: 2009-09-17 14:00:58 -0700 (Thu, 17 Sep 2009) $ + * + * ==================================================================== + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.commons.ssl; + +import javax.net.ssl.HandshakeCompletedListener; +import javax.net.ssl.SSLSession; +import javax.net.ssl.SSLSocket; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.net.InetAddress; +import java.net.Socket; +import java.net.SocketAddress; +import java.net.SocketException; +import java.nio.channels.SocketChannel; + +/** + * @author Credit Union Central of British Columbia + * @author www.cucbc.com + * @author juliusdavies@cucbc.com + * @since 16-Aug-2006 + */ +public class SSLSocketWrapper extends SSLSocket { + protected Socket s; + + public SSLSocketWrapper(Socket s) { + this.s = s; + } + + /* javax.net.ssl.SSLSocket */ + + public void addHandshakeCompletedListener(HandshakeCompletedListener hcl) { + if (s instanceof SSLSocket) { + ((SSLSocket) s).addHandshakeCompletedListener(hcl); + } + } + + public void removeHandshakeCompletedListener(HandshakeCompletedListener hcl) { + if (s instanceof SSLSocket) { + ((SSLSocket) s).removeHandshakeCompletedListener(hcl); + } + } + + public String[] getSupportedCipherSuites() { + if (s instanceof SSLSocket) { + return ((SSLSocket) s).getSupportedCipherSuites(); + } else { + return null; + } + } + + public boolean getEnableSessionCreation() { + if (s instanceof SSLSocket) { + return ((SSLSocket) s).getEnableSessionCreation(); + } else { + return false; + } + } + + public String[] getEnabledCipherSuites() { + if (s instanceof SSLSocket) { + return ((SSLSocket) s).getEnabledCipherSuites(); + } else { + return null; + } + } + + public String[] getSupportedProtocols() { + if (s instanceof SSLSocket) { + return ((SSLSocket) s).getSupportedProtocols(); + } else { + return null; + } + } + + public String[] getEnabledProtocols() { + if (s instanceof SSLSocket) { + return ((SSLSocket) s).getEnabledProtocols(); + } else { + return null; + } + } + + public SSLSession getSession() { + if (s instanceof SSLSocket) { + return ((SSLSocket) s).getSession(); + } else { + return null; + } + } + + public boolean getUseClientMode() { + if (s instanceof SSLSocket) { + return ((SSLSocket) s).getUseClientMode(); + } else { + return false; + } + } + + public boolean getNeedClientAuth() { + if (s instanceof SSLSocket) { + return ((SSLSocket) s).getNeedClientAuth(); + } else { + return false; + } + } + + public boolean getWantClientAuth() { + if (s instanceof SSLSocket) { + return ((SSLSocket) s).getWantClientAuth(); + } else { + return false; + } + } + + public void setEnabledCipherSuites(String[] cs) { + if (s instanceof SSLSocket) { + ((SSLSocket) s).setEnabledCipherSuites(cs); + } + } + + public void setEnabledProtocols(String[] ep) { + if (s instanceof SSLSocket) { + ((SSLSocket) s).setEnabledProtocols(ep); + } + } + + public void startHandshake() throws IOException { + if (s instanceof SSLSocket) { + ((SSLSocket) s).startHandshake(); + } + } + + public void setUseClientMode(boolean b) { + if (s instanceof SSLSocket) { + ((SSLSocket) s).setUseClientMode(b); + } + } + + public void setNeedClientAuth(boolean b) { + if (s instanceof SSLSocket) { + ((SSLSocket) s).setNeedClientAuth(b); + } + } + + public void setWantClientAuth(boolean b) { + if (s instanceof SSLSocket) { + ((SSLSocket) s).setWantClientAuth(b); + } + } + + public void setEnableSessionCreation(boolean b) { + if (s instanceof SSLSocket) { + ((SSLSocket) s).setEnableSessionCreation(b); + } + } + + /* java.net.Socket */ + + public SocketChannel getChannel() { + return s.getChannel(); + } + + public InetAddress getInetAddress() { + return s.getInetAddress(); + } + + public boolean getKeepAlive() throws SocketException { + return s.getKeepAlive(); + } + + public InetAddress getLocalAddress() { + return s.getLocalAddress(); + } + + public int getLocalPort() { + return s.getLocalPort(); + } + + public SocketAddress getLocalSocketAddress() { + return s.getLocalSocketAddress(); + } + + public boolean getOOBInline() throws SocketException { + return s.getOOBInline(); + } + + public int getPort() { + return s.getPort(); + } + + public int getReceiveBufferSize() throws SocketException { + return s.getReceiveBufferSize(); + } + + public SocketAddress getRemoteSocketAddress() { + return s.getRemoteSocketAddress(); + } + + public boolean getReuseAddress() throws SocketException { + return s.getReuseAddress(); + } + + public int getSendBufferSize() throws SocketException { + return s.getSendBufferSize(); + } + + public int getSoLinger() throws SocketException { + return s.getSoLinger(); + } + + public int getSoTimeout() throws SocketException { + return s.getSoTimeout(); + } + + public boolean getTcpNoDelay() throws SocketException { + return s.getTcpNoDelay(); + } + + public int getTrafficClass() throws SocketException { + return s.getTrafficClass(); + } + + public boolean isBound() { + return s.isBound(); + } + + public boolean isClosed() { + return s.isClosed(); + } + + public boolean isConnected() { + return s.isConnected(); + } + + public boolean isInputShutdown() { + return s.isInputShutdown(); + } + + public boolean isOutputShutdown() { + return s.isOutputShutdown(); + } + + public void sendUrgentData(int data) throws IOException { + s.sendUrgentData(data); + } + + public void setKeepAlive(boolean on) throws SocketException { + s.setKeepAlive(on); + } + + public void setOOBInline(boolean on) throws SocketException { + s.setOOBInline(on); + } + + public void setReceiveBufferSize(int size) throws SocketException { + s.setReceiveBufferSize(size); + } + + public void setReuseAddress(boolean on) throws SocketException { + s.setReuseAddress(on); + } + + public void setSendBufferSize(int size) throws SocketException { + s.setSendBufferSize(size); + } + + public void setSoLinger(boolean on, int l) throws SocketException { + s.setSoLinger(on, l); + } + + public void setSoTimeout(int timeout) throws SocketException { + s.setSoTimeout(timeout); + } + + public void setTcpNoDelay(boolean on) throws SocketException { + s.setTcpNoDelay(on); + } + + public void setTrafficClass(int tc) throws SocketException { + s.setTrafficClass(tc); + } + + public void shutdownInput() throws IOException { + s.shutdownInput(); + } + + public void shutdownOutput() throws IOException { + s.shutdownOutput(); + } + + public String toString() { + return s.toString(); + } + + /* Java 1.5 + public void setPerformancePreferences(int connectionTime, int latency, int bandwidth) + { + s.setPerformancePreferences( connectionTime, latency, bandwidth ); + } + */ + + public void bind(SocketAddress bindpoint) throws IOException { + s.bind(bindpoint); + } + + public void close() throws IOException { + s.close(); + } + + public void connect(SocketAddress endpoint) throws IOException { + s.connect(endpoint); + } + + public void connect(SocketAddress endpoint, int timeout) throws IOException { + s.connect(endpoint, timeout); + } + + public InputStream getInputStream() throws IOException { + return s.getInputStream(); + } + + public OutputStream getOutputStream() throws IOException { + return s.getOutputStream(); + } + +} http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/23c1fd12/3rdparty/not-yet-commons-ssl/src/main/java/org/apache/commons/ssl/SSLWrapperFactory.java ---------------------------------------------------------------------- diff --git a/3rdparty/not-yet-commons-ssl/src/main/java/org/apache/commons/ssl/SSLWrapperFactory.java b/3rdparty/not-yet-commons-ssl/src/main/java/org/apache/commons/ssl/SSLWrapperFactory.java new file mode 100644 index 0000000..c8fa432 --- /dev/null +++ b/3rdparty/not-yet-commons-ssl/src/main/java/org/apache/commons/ssl/SSLWrapperFactory.java @@ -0,0 +1,110 @@ +/* + * $HeadURL: http://juliusdavies.ca/svn/not-yet-commons-ssl/tags/commons-ssl-0.3.16/src/java/org/apache/commons/ssl/SSLWrapperFactory.java $ + * $Revision: 155 $ + * $Date: 2009-09-17 14:00:58 -0700 (Thu, 17 Sep 2009) $ + * + * ==================================================================== + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.commons.ssl; + +import javax.net.ssl.SSLServerSocket; +import javax.net.ssl.SSLSocket; +import java.io.IOException; +import java.net.Socket; + +/** + * @author Credit Union Central of British Columbia + * @author www.cucbc.com + * @author juliusdavies@cucbc.com + * @since 19-Sep-2006 + */ +public interface SSLWrapperFactory { + + /** + * Wraps an SSLSSocket. + * + * @param s SSLSocket to wrap. + * @return The new wrapped SSLSocket. + * @throws java.io.IOException if wrapping failed + */ + public Socket wrap(Socket s) throws IOException; + + /** + * Wraps an SSLServerSocket. + * + * @param s The SSLServerSocket to wrap. + * @param ssl The SSL object that created the SSLServerSocket. + * This way some important commons-ssl config can be applied + * to the returned socket. + * @return The new wrapped SSLServerSocket. + * @throws java.io.IOException if wrapping failed + */ + public SSLServerSocket wrap(SSLServerSocket s, SSL ssl) + throws IOException; + + + /** + * NO_WRAP doesn't wrap the SSLSocket. It does wrap the SSLServerSocket + * so that we can do the usual housekeeping after accept() that we like to + * do on every socket. E.g. setSoTimeout, setEnabledProtocols, + * setEnabledCiphers, setUseClientMode, and the hostname verifier (which + * should be very rare on SSLServerSockets!). + */ + public final static SSLWrapperFactory NO_WRAP = new SSLWrapperFactory() { + // Notice! No wrapping! + public Socket wrap(Socket s) { return s; } + + // We still wrap the ServerSocket, but we don't wrap the result of the + // the accept() call. + public SSLServerSocket wrap(SSLServerSocket s, SSL ssl) + throws IOException { + // Can't wrap with Java 1.3 because SSLServerSocket's constructor has + // default access instead of protected access in Java 1.3. + boolean java13 = JavaImpl.isJava13(); + return java13 ? s : new SSLServerSocketWrapper(s, ssl, this); + } + }; + + /** + * DUMB_WRAP is useful to make sure that wrapping the sockets doesn't break + * anything. It doesn't actually do anything interesting in its wrapped + * implementations. + */ + public final static SSLWrapperFactory DUMB_WRAP = new SSLWrapperFactory() { + public Socket wrap(Socket s) { return new SSLSocketWrapper(s); } + + public SSLServerSocket wrap(SSLServerSocket s, SSL ssl) + throws IOException { + // Can't wrap with Java 1.3 because SSLServerSocket's constructor has + // default access instead of protected access in Java 1.3. + boolean java13 = JavaImpl.isJava13(); + return java13 ? s : new SSLServerSocketWrapper(s, ssl, this); + } + }; + + +} http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/23c1fd12/3rdparty/not-yet-commons-ssl/src/main/java/org/apache/commons/ssl/TomcatServerXML.java ---------------------------------------------------------------------- diff --git a/3rdparty/not-yet-commons-ssl/src/main/java/org/apache/commons/ssl/TomcatServerXML.java b/3rdparty/not-yet-commons-ssl/src/main/java/org/apache/commons/ssl/TomcatServerXML.java new file mode 100644 index 0000000..382c9f0 --- /dev/null +++ b/3rdparty/not-yet-commons-ssl/src/main/java/org/apache/commons/ssl/TomcatServerXML.java @@ -0,0 +1,231 @@ +/* + * $HeadURL: http://juliusdavies.ca/svn/not-yet-commons-ssl/tags/commons-ssl-0.3.16/src/java/org/apache/commons/ssl/TomcatServerXML.java $ + * $Revision: 121 $ + * $Date: 2007-11-13 21:26:57 -0800 (Tue, 13 Nov 2007) $ + * + * ==================================================================== + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.commons.ssl; + +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.NodeList; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.Collections; +import java.util.Map; +import java.util.SortedMap; +import java.util.TreeMap; + +/** + * @author Credit Union Central of British Columbia + * @author www.cucbc.com + * @author juliusdavies@cucbc.com + * @since 22-Feb-2007 + */ +public class TomcatServerXML { + private final static LogWrapper log = LogWrapper.getLogger(TomcatServerXML.class); + + /** + * KeyMaterial extracted from Tomcat's conf/server.xml. There might be + * several KeyMaterials to extract if Tomcat has different SSL Certificates + * listening on different ports. This particular KeyMaterial will come from + * the lowest secure port that Tomcat is properly configured to open. + */ + public final static KeyMaterial KEY_MATERIAL; + + /** + * TrustMaterial extracted from Tomcat's conf/server.xml. There might be + * several TrustMaterials to extract if Tomcat has different SSL Certificates + * listening on different ports. This particular TrustMaterial will come + * from the lowest secure port that Tomcat is properly configured to open. + *

+ * There's a good chance this will be set to TrustMaterial.DEFAULT (which + * use's the JVM's '$JAVA_HOME/jre/lib/security/cacerts' file). + *

+ * Note: With SSLServerSockets, TrustMaterial only matters when the + * incoming client socket (SSLSocket) presents a client certificate. + *

+ */ + public final static TrustMaterial TRUST_MATERIAL; + + /** + * new Integer( port ) --> KeyMaterial mapping of SSL Certificates found + * inside Tomcat's conf/server.xml file. + */ + public final static SortedMap KEY_MATERIAL_BY_PORT; + + /** + * new Integer( port ) --> TrustMaterial mapping of SSL configuration + * found inside Tomcat's conf/server.xml file. + *

+ * Many of these will probably be TrustMaterial.DEFAULT (which uses the + * JVM's '$JAVA_HOME/jre/lib/security/cacerts' file). + *

+ * Note: With SSLServerSockets, TrustMaterial only matters when the + * incoming client socket (SSLSocket) presents a client certificate. + *

+ */ + public final static SortedMap TRUST_MATERIAL_BY_PORT; + + static { + String tomcatHome = System.getProperty("catalina.home"); + String serverXML = tomcatHome + "/conf/server.xml"; + TreeMap keyMap = new TreeMap(); + TreeMap trustMap = new TreeMap(); + InputStream in = null; + Document doc = null; + try { + if (tomcatHome != null) { + File f = new File(serverXML); + if (f.exists()) { + try { + in = new FileInputStream(serverXML); + } + catch (IOException ioe) { + // oh well, no soup for us. + log.warn("Commons-SSL failed to load Tomcat's [" + serverXML + "] " + ioe); + } + } + } + if (in != null) { + DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); + try { + DocumentBuilder db = dbf.newDocumentBuilder(); + doc = db.parse(in); + } + catch (Exception e) { + log.warn("Commons-SSL failed to parse Tomcat's [" + serverXML + "] " + e); + } + } + if (doc != null) { + loadTomcatConfig(doc, keyMap, trustMap); + } + } + finally { + if (in != null) { + try { in.close(); } catch (Exception e) { /* . */ } + } + } + KEY_MATERIAL_BY_PORT = Collections.unmodifiableSortedMap(keyMap); + TRUST_MATERIAL_BY_PORT = Collections.unmodifiableSortedMap(trustMap); + + KeyMaterial km = null; + TrustMaterial tm = null; + if (!keyMap.isEmpty()) { + km = (KeyMaterial) keyMap.get(keyMap.firstKey()); + } + if (!trustMap.isEmpty()) { + tm = (TrustMaterial) trustMap.get(trustMap.firstKey()); + } + KEY_MATERIAL = km; + TRUST_MATERIAL = tm; + + } + + private static void loadTomcatConfig(Document d, Map keyMap, Map trustMap) { + final String userHome = System.getProperty("user.home"); + NodeList nl = d.getElementsByTagName("Connector"); + for (int i = 0; i < nl.getLength(); i++) { + KeyMaterial km = null; + TrustMaterial tm = null; + + Element element = (Element) nl.item(i); + String secure = element.getAttribute("secure"); + String portString = element.getAttribute("port"); + Integer port = null; + String pass; + try { + portString = portString != null ? portString.trim() : ""; + port = new Integer(portString); + } + catch (NumberFormatException nfe) { + // oh well + } + if (port != null && Util.isYes(secure)) { + // Key Material + String keystoreFile = element.getAttribute("keystoreFile"); + pass = element.getAttribute("keystorePass"); + if (!element.hasAttribute("keystoreFile")) { + keystoreFile = userHome + "/.keystore"; + } + if (!element.hasAttribute("keystorePass")) { + pass = "changeit"; + } + char[] keystorePass = pass != null ? pass.toCharArray() : null; + + // Trust Material + String truststoreFile = element.getAttribute("truststoreFile"); + pass = element.getAttribute("truststorePass"); + if (!element.hasAttribute("truststoreFile")) { + truststoreFile = null; + } + if (!element.hasAttribute("truststorePass")) { + pass = null; + } + char[] truststorePass = pass != null ? pass.toCharArray() : null; + + + if (keystoreFile == null) { + km = null; + } else { + try { + km = new KeyMaterial(keystoreFile, keystorePass); + } + catch (Exception e) { + log.warn("Commons-SSL failed to load [" + keystoreFile + "] " + e); + } + } + if (truststoreFile == null) { + tm = TrustMaterial.DEFAULT; + } else { + try { + tm = new TrustMaterial(truststoreFile, truststorePass); + } + catch (Exception e) { + log.warn("Commons-SSL failed to load [" + truststoreFile + "] " + e); + } + } + + Object o = keyMap.put(port, km); + if (o != null) { + log.debug("Commons-SSL TomcatServerXML keyMap clobbered port: " + port); + } + o = trustMap.put(port, tm); + if (o != null) { + log.debug("Commons-SSL TomcatServerXML trustMap clobbered port: " + port); + } + } + } + } + +} http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/23c1fd12/3rdparty/not-yet-commons-ssl/src/main/java/org/apache/commons/ssl/TrustChain.java ---------------------------------------------------------------------- diff --git a/3rdparty/not-yet-commons-ssl/src/main/java/org/apache/commons/ssl/TrustChain.java b/3rdparty/not-yet-commons-ssl/src/main/java/org/apache/commons/ssl/TrustChain.java new file mode 100644 index 0000000..4340e6d --- /dev/null +++ b/3rdparty/not-yet-commons-ssl/src/main/java/org/apache/commons/ssl/TrustChain.java @@ -0,0 +1,219 @@ +/* + * $HeadURL: http://juliusdavies.ca/svn/not-yet-commons-ssl/tags/commons-ssl-0.3.16/src/java/org/apache/commons/ssl/TrustChain.java $ + * $Revision: 138 $ + * $Date: 2008-03-03 23:50:07 -0800 (Mon, 03 Mar 2008) $ + * + * ==================================================================== + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.commons.ssl; + +import java.io.IOException; +import java.security.KeyStore; +import java.security.KeyStoreException; +import java.security.NoSuchAlgorithmException; +import java.security.cert.CertificateException; +import java.security.cert.X509Certificate; +import java.util.Collections; +import java.util.Enumeration; +import java.util.HashSet; +import java.util.Iterator; +import java.util.Set; +import java.util.SortedSet; +import java.util.TreeSet; + +/** + * @author Credit Union Central of British Columbia + * @author www.cucbc.com + * @author juliusdavies@cucbc.com + * @since 27-Feb-2006 + */ +public class TrustChain { + private final Set trustMaterial = + Collections.synchronizedSet(new HashSet()); + private SortedSet x509Certificates = null; + private KeyStore unifiedKeyStore = null; + + public TrustChain() { + } + + public synchronized KeyStore getUnifiedKeyStore() + throws KeyStoreException, IOException, NoSuchAlgorithmException, + CertificateException { + + // x509Certificates serves as our "cache available" indicator. + if (x509Certificates != null) { + return unifiedKeyStore; + } + + // First, extract all the X509Certificates from this TrustChain. + this.x509Certificates = new TreeSet(Certificates.COMPARE_BY_EXPIRY); + Iterator it = trustMaterial.iterator(); + while (it.hasNext()) { + TrustMaterial tm = (TrustMaterial) it.next(); + KeyStore ks = tm.getKeyStore(); + if (ks != null) { + Enumeration en = ks.aliases(); + while (en.hasMoreElements()) { + String alias = (String) en.nextElement(); + if (ks.isCertificateEntry(alias)) { + X509Certificate cert; + cert = (X509Certificate) ks.getCertificate(alias); + if (!x509Certificates.contains(cert)) { + x509Certificates.add(cert); + } + } + } + } + } + + // Now that the X509Certificates are extracted, create the unified + // keystore. + it = x509Certificates.iterator(); + KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType()); + ks.load(null, null); + int count = 0; + while (it.hasNext()) { + X509Certificate cert = (X509Certificate) it.next(); + // The "count" should keep the aliases unique (is that important?) + String alias = "commons-ssl-" + count; + ks.setCertificateEntry(alias, cert); + count++; + } + this.unifiedKeyStore = ks; + return unifiedKeyStore; + } + + public synchronized void addTrustMaterial(TrustChain tc) { + this.x509Certificates = null; // invalidate cache + if (tc instanceof TrustMaterial) { + trustMaterial.add(tc); + } + // If duplicates are added, the Set will remove them. + trustMaterial.addAll(tc.trustMaterial); + } + + public boolean contains(TrustChain tc) { + if (tc instanceof TrustMaterial) { + return trustMaterial.contains(tc); + } else { + return trustMaterial.containsAll(tc.trustMaterial); + } + } + + public boolean contains(X509Certificate cert) + throws KeyStoreException, IOException, NoSuchAlgorithmException, + CertificateException { + return getCertificates().contains(cert); + } + + public Object getTrustManagerFactory() + throws NoSuchAlgorithmException, KeyStoreException, IOException, + CertificateException { + KeyStore uks = getUnifiedKeyStore(); + if (uks != null) { + return JavaImpl.newTrustManagerFactory(uks); + } else { + return null; + } + } + + /** + * @return Array of TrustManager[] - presumably these will be dropped into + * a call to SSLContext.init(). Note: returns null if this + * TrustChain doesn't contain anything to trust. + * @throws java.security.NoSuchAlgorithmException serious problems + * @throws java.security.KeyStoreException serious problems + * @throws java.io.IOException serious problems + * @throws java.security.cert.CertificateException serious problems + */ + public Object[] getTrustManagers() + throws NoSuchAlgorithmException, KeyStoreException, IOException, + CertificateException { + Object tmf = getTrustManagerFactory(); + return tmf != null ? JavaImpl.getTrustManagers(tmf) : null; + } + + /** + * @return All X509Certificates contained in this TrustChain as a SortedSet. + * The X509Certificates are sorted based on expiry date. + *

+ * See org.apache.commons.ssl.Certificates.COMPARE_BY_EXPIRY. + * @throws java.security.KeyStoreException serious problems + * @throws java.io.IOException serious problems + * @throws java.security.NoSuchAlgorithmException serious problems + * @throws java.security.cert.CertificateException serious problems + */ + public synchronized SortedSet getCertificates() + throws KeyStoreException, IOException, NoSuchAlgorithmException, + CertificateException { + if (x509Certificates == null) { + getUnifiedKeyStore(); + } + return Collections.unmodifiableSortedSet(x509Certificates); + } + + /** + * @return Count of all X509Certificates contained in this TrustChain. + * @throws java.security.KeyStoreException + * @throws java.io.IOException + * @throws java.security.NoSuchAlgorithmException + * @throws java.security.cert.CertificateException + */ + public synchronized int getSize() + throws KeyStoreException, IOException, NoSuchAlgorithmException, + CertificateException { + return getCertificates().size(); + } + + /** + * @return Count of all X509Certificates contained in this TrustChain. + * @throws java.security.KeyStoreException + * @throws java.io.IOException + * @throws java.security.NoSuchAlgorithmException + * @throws java.security.cert.CertificateException + */ + public synchronized boolean isEmpty() + throws KeyStoreException, IOException, NoSuchAlgorithmException, + CertificateException { + return getCertificates().isEmpty(); + } + + protected boolean containsTrustAll() { + Iterator it = trustMaterial.iterator(); + while (it.hasNext()) { + TrustChain tc = (TrustChain) it.next(); + if (tc == this) { + continue; + } + if (tc.containsTrustAll()) { + return true; + } + } + return false; + } + +} http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/23c1fd12/3rdparty/not-yet-commons-ssl/src/main/java/org/apache/commons/ssl/TrustMaterial.java ---------------------------------------------------------------------- diff --git a/3rdparty/not-yet-commons-ssl/src/main/java/org/apache/commons/ssl/TrustMaterial.java b/3rdparty/not-yet-commons-ssl/src/main/java/org/apache/commons/ssl/TrustMaterial.java new file mode 100644 index 0000000..ca6d5a0 --- /dev/null +++ b/3rdparty/not-yet-commons-ssl/src/main/java/org/apache/commons/ssl/TrustMaterial.java @@ -0,0 +1,281 @@ +/* + * $HeadURL: http://juliusdavies.ca/svn/not-yet-commons-ssl/tags/commons-ssl-0.3.16/src/java/org/apache/commons/ssl/TrustMaterial.java $ + * $Revision: 171 $ + * $Date: 2014-05-09 08:15:26 -0700 (Fri, 09 May 2014) $ + * + * ==================================================================== + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.commons.ssl; + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.net.URL; +import java.security.GeneralSecurityException; +import java.security.KeyStore; +import java.security.KeyStoreException; +import java.security.cert.Certificate; +import java.security.cert.X509Certificate; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.Enumeration; +import java.util.Iterator; + +/** + * @author Credit Union Central of British Columbia + * @author www.cucbc.com + * @author juliusdavies@cucbc.com + * @since 27-Feb-2006 + */ +public class TrustMaterial extends TrustChain { + final static int SIMPLE_TRUST_TYPE_TRUST_ALL = 1; + final static int SIMPLE_TRUST_TYPE_TRUST_THIS_JVM = 2; + + /** + * Might be null if "$JAVA_HOME/jre/lib/security/cacerts" doesn't exist. + */ + public final static TrustMaterial CACERTS; + + /** + * Might be null if "$JAVA_HOME/jre/lib/security/jssecacerts" doesn't exist. + */ + public final static TrustMaterial JSSE_CACERTS; + + /** + * Should never be null (unless both CACERTS and JSSE_CACERTS are not + * present???). Is either CACERTS or JSSE_CACERTS. Priority given to + * JSSE_CACERTS, but 99.9% of the time it's CACERTS, since JSSE_CACERTS + * is almost never present. + */ + public final static TrustMaterial DEFAULT; + + static { + JavaImpl.load(); + String javaHome = System.getProperty("java.home"); + String pathToCacerts = javaHome + "/lib/security/cacerts"; + String pathToJSSECacerts = javaHome + "/lib/security/jssecacerts"; + TrustMaterial cacerts = null; + TrustMaterial jssecacerts = null; + try { + File f = new File(pathToCacerts); + if (f.exists()) { + cacerts = new TrustMaterial(pathToCacerts); + } + } + catch (Exception e) { + e.printStackTrace(); + } + try { + File f = new File(pathToJSSECacerts); + if (f.exists()) { + jssecacerts = new TrustMaterial(pathToJSSECacerts); + } + } + catch (Exception e) { + e.printStackTrace(); + } + + CACERTS = cacerts; + JSSE_CACERTS = jssecacerts; + if (JSSE_CACERTS != null) { + DEFAULT = JSSE_CACERTS; + } else { + DEFAULT = CACERTS; + } + } + + public final static TrustMaterial TRUST_ALL = + new TrustMaterial(SIMPLE_TRUST_TYPE_TRUST_ALL); + + public final static TrustMaterial TRUST_THIS_JVM = + new TrustMaterial(SIMPLE_TRUST_TYPE_TRUST_THIS_JVM); + + public final int simpleTrustType; + private final KeyStore jks; + + private TrustMaterial(int simpleTrustType) { + this(null, simpleTrustType); + } + + TrustMaterial(KeyStore jks, int simpleTrustType) { + if (jks == null && simpleTrustType != 0) { + // Just use CACERTS as a place holder, since Java 5 and 6 seem to get + // upset when we hand SSLContext null TrustManagers. See + // Java14.initSSL(), which despite its name, is also used + // with Java5 and Java6. + this.jks = CACERTS != null ? CACERTS.jks : JSSE_CACERTS.jks; + } else { + this.jks = jks; + } + addTrustMaterial(this); + this.simpleTrustType = simpleTrustType; + } + + public TrustMaterial(Collection x509Certs) + throws GeneralSecurityException, IOException { + KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType()); + ks.load(null, null); + loadCerts(ks, x509Certs); + this.jks = ks; + addTrustMaterial(this); + + // We're not a simple trust type, so set value to 0. + // Only TRUST_ALL and TRUST_THIS_JVM are simple trust types. + this.simpleTrustType = 0; + } + + public TrustMaterial(X509Certificate x509Cert) + throws GeneralSecurityException, IOException { + this(Collections.singleton(x509Cert)); + } + + public TrustMaterial(X509Certificate[] x509Certs) + throws GeneralSecurityException, IOException { + this(Arrays.asList(x509Certs)); + } + + public TrustMaterial(byte[] pemBase64) + throws GeneralSecurityException, IOException { + this(pemBase64, null); + } + + public TrustMaterial(InputStream pemBase64) + throws GeneralSecurityException, IOException { + this(Util.streamToBytes(pemBase64)); + } + + public TrustMaterial(String pathToPemFile) + throws GeneralSecurityException, IOException { + this(new FileInputStream(pathToPemFile)); + } + + public TrustMaterial(File pemFile) + throws GeneralSecurityException, IOException { + this(new FileInputStream(pemFile)); + } + + public TrustMaterial(URL urlToPemFile) + throws GeneralSecurityException, IOException { + this(urlToPemFile.openStream()); + } + + public TrustMaterial(String pathToJksFile, char[] password) + throws GeneralSecurityException, IOException { + this(new File(pathToJksFile), password); + } + + public TrustMaterial(File jksFile, char[] password) + throws GeneralSecurityException, IOException { + this(new FileInputStream(jksFile), password); + } + + public TrustMaterial(URL urlToJKS, char[] password) + throws GeneralSecurityException, IOException { + this(urlToJKS.openStream(), password); + } + + public TrustMaterial(InputStream jks, char[] password) + throws GeneralSecurityException, IOException { + this(Util.streamToBytes(jks), password); + } + + public TrustMaterial(byte[] jks, char[] password) + throws GeneralSecurityException, IOException { + + KeyStoreBuilder.BuildResult br; + br = KeyStoreBuilder.parse(jks, password, null, true); + if (br.jks != null) { + // If we've been given a keystore, just use that. + this.jks = br.jks; + } else { + // Otherwise we need to build a keystore from what we were given. + KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType()); + if (br.chains != null && !br.chains.isEmpty()) { + Certificate[] c = (Certificate[]) br.chains.get(0); + if (c.length > 0) { + ks.load(null, password); + loadCerts(ks, Arrays.asList(c)); + } + } + this.jks = ks; + } + + // Should validate our keystore to make sure it has at least ONE + // certificate entry: + KeyStore ks = this.jks; + boolean hasCertificates = false; + Enumeration en = ks.aliases(); + while (en.hasMoreElements()) { + String alias = (String) en.nextElement(); + if (ks.isCertificateEntry(alias)) { + hasCertificates = true; + break; + } + } + if (!hasCertificates) { + throw new KeyStoreException("TrustMaterial couldn't load any certificates to trust!"); + } + + addTrustMaterial(this); + + // We're not a simple trust type, so set value to 0. + // Only TRUST_ALL and TRUST_THIS_JVM are simple trust types. + this.simpleTrustType = 0; + } + + public KeyStore getKeyStore() { + return jks; + } + + private static void loadCerts(KeyStore ks, Collection certs) + throws KeyStoreException { + Iterator it = certs.iterator(); + int count = 0; + while (it.hasNext()) { + X509Certificate cert = (X509Certificate) it.next(); + + // I could be fancy and parse out the CN field from the + // certificate's subject, but these names don't actually matter + // at all - I think they just have to be unique. + String cn = Certificates.getCN(cert); + String alias = cn + "_" + count; + ks.setCertificateEntry(alias, cert); + count++; + } + } + + protected boolean containsTrustAll() { + boolean yes = this.simpleTrustType == SIMPLE_TRUST_TYPE_TRUST_ALL; + if ( !yes ) { + yes = super.containsTrustAll(); + } + return yes; + } + +} http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/23c1fd12/3rdparty/not-yet-commons-ssl/src/main/java/org/apache/commons/ssl/Util.java ---------------------------------------------------------------------- diff --git a/3rdparty/not-yet-commons-ssl/src/main/java/org/apache/commons/ssl/Util.java b/3rdparty/not-yet-commons-ssl/src/main/java/org/apache/commons/ssl/Util.java new file mode 100644 index 0000000..45f716a --- /dev/null +++ b/3rdparty/not-yet-commons-ssl/src/main/java/org/apache/commons/ssl/Util.java @@ -0,0 +1,452 @@ +/* + * $HeadURL: http://juliusdavies.ca/svn/not-yet-commons-ssl/tags/commons-ssl-0.3.16/src/java/org/apache/commons/ssl/Util.java $ + * $Revision: 180 $ + * $Date: 2014-09-23 11:33:47 -0700 (Tue, 23 Sep 2014) $ + * + * ==================================================================== + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.commons.ssl; + +import org.apache.commons.ssl.util.ByteArrayReadLine; +import org.apache.commons.ssl.util.IPAddressParser; + +import java.io.ByteArrayInputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.security.KeyStore; +import java.security.KeyStoreException; +import java.security.cert.Certificate; +import java.util.Arrays; +import java.util.Enumeration; +import java.util.LinkedList; +import java.util.Map; +import java.util.Set; +import java.util.StringTokenizer; +import java.util.TreeMap; +import java.util.TreeSet; + +/** + * @author Credit Union Central of British Columbia + * @author www.cucbc.com + * @author juliusdavies@cucbc.com + * @since 28-Feb-2006 + */ +public class Util { + public final static int SIZE_KEY = 0; + public final static int LAST_READ_KEY = 1; + + /** + * True if the Keystores have the same # of entries, have the same set of aliases, and all the certificate-chains + * (of the certificate entries) match. Does not check the private keys for equality, since we + * don't bother taking the passwords to get at them. + */ + public static boolean equals(KeyStore ks1, KeyStore ks2) throws KeyStoreException { + if (ks1 == null || ks2 == null) { + return ks1 == null && ks2 == null; + } + Set aliases1 = aliases(ks1); + Set aliases2 = aliases(ks2); + if (aliases1.equals(aliases2)) { + for (String s : aliases1) { + if (ks1.isCertificateEntry(s) != ks2.isCertificateEntry(s)) { + return false; + } + if (ks1.isKeyEntry(s) != ks2.isKeyEntry(s)) { + return false; + } + if (ks1.isCertificateEntry(s)) { + Certificate[] cc1 = ks1.getCertificateChain(s); + Certificate[] cc2 = ks2.getCertificateChain(s); + if (!Arrays.equals(cc1, cc2)) { + return false; + } + + Certificate c1 = ks1.getCertificate(s); + Certificate c2 = ks2.getCertificate(s); + if (!c1.equals(c2)) { + return false; + } + } + + // should we bother checking keys? maybe one day.... + } + } + return true; + } + + private static Set aliases(KeyStore ks) throws KeyStoreException { + Set aliases = new TreeSet(); + Enumeration en = ks.aliases(); + while (en.hasMoreElements()) { + aliases.add(en.nextElement()); + } + return aliases; + } + + public static boolean isYes(String yesString) { + if (yesString == null) { + return false; + } + String s = yesString.trim().toUpperCase(); + return "1".equals(s) || "YES".equals(s) || "TRUE".equals(s) || + "ENABLE".equals(s) || "ENABLED".equals(s) || "Y".equals(s) || + "ON".equals(s); + } + + public static String trim(final String s) { + if (s == null || "".equals(s)) { + return s; + } + int i = 0; + int j = s.length() - 1; + while (isWhiteSpace(s.charAt(i))) { + i++; + } + while (isWhiteSpace(s.charAt(j))) { + j--; + } + return j >= i ? s.substring(i, j + 1) : ""; + } + + public static boolean isWhiteSpace(final char c) { + switch (c) { + case 0: + case ' ': + case '\t': + case '\n': + case '\r': + case '\f': + return true; + default: + return false; + } + } + + public static void pipeStream(InputStream in, OutputStream out) + throws IOException { + pipeStream(in, out, true); + } + + public static void pipeStream(InputStream in, OutputStream out, + boolean autoClose) + throws IOException { + byte[] buf = new byte[8192]; + IOException ioe = null; + try { + int bytesRead = in.read(buf); + while (bytesRead >= 0) { + if (bytesRead > 0) { + out.write(buf, 0, bytesRead); + } + bytesRead = in.read(buf); + } + } + finally { + // Probably it's best to let consumer call "close", but I'm usually + // the consumer, and I want to be lazy. [Julius, November 20th, 2006] + try { in.close(); } catch (IOException e) { ioe = e; } + if (autoClose) { + try { out.close(); } catch (IOException e) { ioe = e; } + } + } + if (ioe != null) { + throw ioe; + } + } + + public static byte[] fileToBytes(final File f) throws IOException { + return streamToBytes(new FileInputStream(f)); + } + + public static byte[] streamToBytes(final ByteArrayInputStream in, + int maxLength) { + byte[] buf = new byte[maxLength]; + int[] status = fill(buf, 0, in); + int size = status[SIZE_KEY]; + if (buf.length != size) { + byte[] smallerBuf = new byte[size]; + System.arraycopy(buf, 0, smallerBuf, 0, size); + buf = smallerBuf; + } + return buf; + } + + public static byte[] streamToBytes(final InputStream in, int maxLength) + throws IOException { + byte[] buf = new byte[maxLength]; + int[] status = fill(buf, 0, in); + int size = status[SIZE_KEY]; + if (buf.length != size) { + byte[] smallerBuf = new byte[size]; + System.arraycopy(buf, 0, smallerBuf, 0, size); + buf = smallerBuf; + } + return buf; + } + + public static byte[] streamToBytes(final InputStream in) throws IOException { + byte[] buf = new byte[4096]; + try { + int[] status = fill(buf, 0, in); + int size = status[SIZE_KEY]; + int lastRead = status[LAST_READ_KEY]; + while (lastRead != -1) { + buf = resizeArray(buf); + status = fill(buf, size, in); + size = status[SIZE_KEY]; + lastRead = status[LAST_READ_KEY]; + } + if (buf.length != size) { + byte[] smallerBuf = new byte[size]; + System.arraycopy(buf, 0, smallerBuf, 0, size); + buf = smallerBuf; + } + } + finally { + in.close(); + } + return buf; + } + + public static byte[] streamToBytes(final ByteArrayInputStream in) { + byte[] buf = new byte[4096]; + int[] status = fill(buf, 0, in); + int size = status[SIZE_KEY]; + int lastRead = status[LAST_READ_KEY]; + while (lastRead != -1) { + buf = resizeArray(buf); + status = fill(buf, size, in); + size = status[SIZE_KEY]; + lastRead = status[LAST_READ_KEY]; + } + if (buf.length != size) { + byte[] smallerBuf = new byte[size]; + System.arraycopy(buf, 0, smallerBuf, 0, size); + buf = smallerBuf; + } + // in.close(); <-- this is a no-op on ByteArrayInputStream. + return buf; + } + + public static int[] fill(final byte[] buf, final int offset, + final InputStream in) + throws IOException { + int read = in.read(buf, offset, buf.length - offset); + int lastRead = read; + if (read == -1) { + read = 0; + } + while (lastRead != -1 && read + offset < buf.length) { + lastRead = in.read(buf, offset + read, buf.length - read - offset); + if (lastRead != -1) { + read += lastRead; + } + } + return new int[]{offset + read, lastRead}; + } + + public static int[] fill(final byte[] buf, final int offset, + final ByteArrayInputStream in) { + int read = in.read(buf, offset, buf.length - offset); + int lastRead = read; + if (read == -1) { + read = 0; + } + while (lastRead != -1 && read + offset < buf.length) { + lastRead = in.read(buf, offset + read, buf.length - read - offset); + if (lastRead != -1) { + read += lastRead; + } + } + return new int[]{offset + read, lastRead}; + } + + public static byte[] resizeArray(final byte[] bytes) { + byte[] biggerBytes = new byte[bytes.length * 2]; + System.arraycopy(bytes, 0, biggerBytes, 0, bytes.length); + return biggerBytes; + } + + public static String pad(String s, final int length, final boolean left) { + if (s == null) { + s = ""; + } + int diff = length - s.length(); + if (diff == 0) { + return s; + } else if (diff > 0) { + StringBuffer sb = new StringBuffer(); + if (left) { + for (int i = 0; i < diff; i++) { + sb.append(' '); + } + } + sb.append(s); + if (!left) { + for (int i = 0; i < diff; i++) { + sb.append(' '); + } + } + return sb.toString(); + } else { + return s; + } + } + + public static Map parseArgs(final String[] cargs) { + Map args = new TreeMap(); + Map ARGS_MATCH = Ping.ARGS_MATCH; + + int l = cargs.length; + final String[] EMPTY_VALUES = {""}; + for (int i = 0; i < l; i++) { + String k = cargs[i]; + Ping.Arg a = (Ping.Arg) ARGS_MATCH.get(k); + if (l > i + 1) { + String v = cargs[++i]; + while (ARGS_MATCH.containsKey(v)) { + args.put(a, EMPTY_VALUES); + a = (Ping.Arg) ARGS_MATCH.get(v); + v = ""; + if (l > i + 1) { + v = cargs[++i]; + } + } + String[] values = new String[1]; + values[0] = v; + args.put(a, values); + if (l > i + 1 && !ARGS_MATCH.containsKey(cargs[i + 1])) { + LinkedList list = new LinkedList(); + list.add(v); + while (l > i + 1 && !ARGS_MATCH.containsKey(cargs[i + 1])) { + v = cargs[++i]; + list.add(v); + } + args.put(a, list.toArray(new String[list.size()])); + } + } else { + args.put(a, EMPTY_VALUES); + } + } + return args; + } + + public static HostPort toAddress(final String target, + final int defaultPort) + throws UnknownHostException { + String host = target; + int port = defaultPort; + StringTokenizer st = new StringTokenizer(target, ":"); + if (st.hasMoreTokens()) { + host = st.nextToken().trim(); + } + if (st.hasMoreTokens()) { + port = Integer.parseInt(st.nextToken().trim()); + } + if (st.hasMoreTokens()) { + throw new IllegalArgumentException("Invalid host: " + target); + } + return new HostPort(host, port); + } + + public static String cipherToAuthType(String cipher) { + if (cipher == null) { + return null; + } + + // SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA ==> "DHE_DSS_EXPORT" + // SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA ==> "DHE_DSS" + // SSL_RSA_WITH_3DES_EDE_CBC_SHA ==> "RSA" + + StringTokenizer st = new StringTokenizer(cipher.trim(), "_"); + if (st.hasMoreTokens()) { + st.nextToken(); // always skip first token + } + if (st.hasMoreTokens()) { + String tok = st.nextToken(); + StringBuffer buf = new StringBuffer(); + buf.append(tok); + if (st.hasMoreTokens()) { + tok = st.nextToken(); + while (!"WITH".equalsIgnoreCase(tok)) { + buf.append('_'); + buf.append(tok); + tok = st.nextToken(); + } + } + return buf.toString(); + } + throw new IllegalArgumentException("not a valid cipher: " + cipher); + } + + /** + * Utility method to make sure IP-literals don't trigger reverse-DNS lookups. + */ + public static InetAddress toInetAddress(String s) throws UnknownHostException { + byte[] ip = IPAddressParser.parseIPv4Literal(s); + if (ip == null) { + ip = IPAddressParser.parseIPv6Literal(s); + } + if (ip != null) { + // Strangely, this prevents Java's annoying SSL reverse-DNS lookup that it + // normally does, even with literal IP addresses. + return InetAddress.getByAddress(s, ip); + } else { + return InetAddress.getByName(s); + } + } + + public static void main(String[] args) throws Exception { + String s = "line1\n\rline2\n\rline3"; + ByteArrayInputStream in = new ByteArrayInputStream(s.getBytes()); + ByteArrayReadLine readLine = new ByteArrayReadLine(in); + String line = readLine.next(); + while (line != null) { + System.out.println(line); + line = readLine.next(); + } + + System.out.println("--------- test 2 ----------"); + + s = "line1\n\rline2\n\rline3\n\r\n\r"; + in = new ByteArrayInputStream(s.getBytes()); + readLine = new ByteArrayReadLine(in); + line = readLine.next(); + while (line != null) { + System.out.println(line); + line = readLine.next(); + } + + } + + +} http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/23c1fd12/3rdparty/not-yet-commons-ssl/src/main/java/org/apache/commons/ssl/Version.java ---------------------------------------------------------------------- diff --git a/3rdparty/not-yet-commons-ssl/src/main/java/org/apache/commons/ssl/Version.java b/3rdparty/not-yet-commons-ssl/src/main/java/org/apache/commons/ssl/Version.java new file mode 100644 index 0000000..04401a3 --- /dev/null +++ b/3rdparty/not-yet-commons-ssl/src/main/java/org/apache/commons/ssl/Version.java @@ -0,0 +1,197 @@ +/* + * $HeadURL: http://juliusdavies.ca/svn/not-yet-commons-ssl/tags/commons-ssl-0.3.16/src/java/org/apache/commons/ssl/Version.java $ + * $Revision: 130 $ + * $Date: 2007-11-14 19:24:15 -0800 (Wed, 14 Nov 2007) $ + * + * ==================================================================== + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.commons.ssl; + +import java.io.File; +import java.io.IOException; +import java.net.URL; +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.Enumeration; +import java.util.jar.JarEntry; +import java.util.jar.JarFile; + +/** + * Extracts tagged version from a subversion $HeadURL: http://juliusdavies.ca/svn/not-yet-commons-ssl/tags/commons-ssl-0.3.16/src/java/org/apache/commons/ssl/Version.java $ property, and prints it + * out nicely on standard out. + *

+ * e.g. If this version came from /tags/commons-ssl-0_3_9/, then Version.java + * will print: "Version: 0.3.9" on standard out. + * + * @author Credit Union Central of British Columbia + * @author www.cucbc.com + * @author juliusdavies@cucbc.com + * @since 14-Nov-2007 + */ +public class Version { + public static final String HEAD_URL = "$HeadURL: http://juliusdavies.ca/svn/not-yet-commons-ssl/tags/commons-ssl-0.3.16/src/java/org/apache/commons/ssl/Version.java $"; + public static final String VERSION; + public static final String COMPILE_TIME; + + static { + // Try to extract a clean version number from svn's HeadURL property: + String v = "UNKNOWN"; + boolean fromBranch = false; + int x = HEAD_URL.lastIndexOf("/tags/"); + if (x >= 0) { + int y = HEAD_URL.indexOf("/", x + "/tags/".length()); + if (y >= 0) { + v = HEAD_URL.substring(x + "/tags/".length(), y); + } + v = v.replace('_', '.'); + v = v.replace('-', '.'); + } else if (HEAD_URL.indexOf("/trunk/") >= 0) { + v = "trunk"; + } else if (HEAD_URL.indexOf("/branches/") >= 0) { + fromBranch = true; + x = HEAD_URL.indexOf("/branches/"); + int y = HEAD_URL.indexOf("/", x + "/branches/".length()); + if (y >= 0) { + v = HEAD_URL.substring(x + "/branches/".length(), y); + } + v = v.replace('_', '.'); + v = v.replace('-', '.'); + } + + String V = v.toUpperCase(); + x = V.indexOf("COMMONS.SSL."); + if (x >= 0) { + v = v.substring(x + "commons.ssl.".length()); + } + VERSION = fromBranch ? "***Branch*** " + v : v; + + // Try to calculate when jar file was compiled: + String s; + try { + s = CompileTime.getCompileTimeString(Version.class); + } + catch (NoClassDefFoundError e) { + s = null; + } + COMPILE_TIME = s; + } + + public static String versionString() { + String v; + if (COMPILE_TIME != null) { + v = CompileTime.formatVersion(VERSION, COMPILE_TIME); + } else { + v = VERSION; + } + return "Version: " + v; + } + + public static void main(String[] args) { + System.out.println(versionString()); + } + + public String toString() { + return versionString(); + } + + + /** + * Searches through a jar file to the find the most recent timestamp of + * all the class files. + */ + private static class CompileTime { + private final static String PATTERN = ".jar!"; + private final static String PREFIX = "file:"; + private final static String DF_FORMAT = "zzz:yyyy-MM-dd/HH:mm:ss.SSS"; + private final static DateFormat DF = new SimpleDateFormat(DF_FORMAT); + + public static String getCompileTimeString(Class clazz) { + String s = clazz.getName(); + s = "/" + s.replace('.', '/') + ".class"; + return getCompileTimeString(s); + } + + private static String getCompileTimeString(String resource) { + try { + Date d = getCompileTime(resource); + return d != null ? DF.format(d) : "[unknown]"; + } + catch (IOException ioe) { + return ioe.toString(); + } + } + + public static Date getCompileTime(String resource) throws IOException { + URL url = CompileTime.class.getResource(resource); + if (url != null) { + String urlString = url.getFile(); + String fileLocation; + int i = urlString.indexOf(PATTERN); + if (i > 0) { + int x = i + PATTERN.length() - 1; + fileLocation = urlString.substring(0, x); + if (fileLocation.startsWith(PREFIX)) { + fileLocation = fileLocation.substring(PREFIX.length()); + } + JarFile jf = new JarFile(fileLocation); + long newestTime = 0; + Enumeration entries = jf.entries(); + while (entries.hasMoreElements()) { + JarEntry entry = (JarEntry) entries.nextElement(); + if (entry.getName().endsWith(".class")) { + newestTime = Math.max(newestTime, entry.getTime()); + } + } + if (newestTime > 0) { + return new Date(newestTime); + } + } else { + File f = new File(urlString); + try { + return new Date(f.lastModified()); + } + catch (Exception e) { + return null; + } + } + } + return null; + } + + public static String formatVersion(String version, String compileTime) { + StringBuffer buf = new StringBuffer(); + buf.append(version); + buf.append(" Compiled: ["); + buf.append(compileTime); + buf.append("]"); + return buf.toString(); + } + + } + +} http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/23c1fd12/3rdparty/not-yet-commons-ssl/src/main/java/org/apache/commons/ssl/X509CertificateChainBuilder.java ---------------------------------------------------------------------- diff --git a/3rdparty/not-yet-commons-ssl/src/main/java/org/apache/commons/ssl/X509CertificateChainBuilder.java b/3rdparty/not-yet-commons-ssl/src/main/java/org/apache/commons/ssl/X509CertificateChainBuilder.java new file mode 100644 index 0000000..fb2642f --- /dev/null +++ b/3rdparty/not-yet-commons-ssl/src/main/java/org/apache/commons/ssl/X509CertificateChainBuilder.java @@ -0,0 +1,204 @@ +/* + * $HeadURL: http://juliusdavies.ca/svn/not-yet-commons-ssl/tags/commons-ssl-0.3.16/src/java/org/apache/commons/ssl/X509CertificateChainBuilder.java $ + * $Revision: 134 $ + * $Date: 2008-02-26 21:30:48 -0800 (Tue, 26 Feb 2008) $ + * + * ==================================================================== + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.commons.ssl; + +import java.io.FileInputStream; +import java.security.InvalidKeyException; +import java.security.NoSuchAlgorithmException; +import java.security.NoSuchProviderException; +import java.security.PublicKey; +import java.security.SignatureException; +import java.security.cert.Certificate; +import java.security.cert.CertificateException; +import java.security.cert.CertificateFactory; +import java.security.cert.X509Certificate; +import java.util.Arrays; +import java.util.Collection; +import java.util.Iterator; +import java.util.LinkedList; + +/** + * Utility for building X509 certificate chains. + * + * @author Credit Union Central of British Columbia + * @author www.cucbc.com + * @author juliusdavies@cucbc.com + * @since 16-Nov-2005 + */ +public class X509CertificateChainBuilder { + /** + * Builds the ordered certificate chain upwards from the startingPoint. + * Uses the supplied X509Certificate[] array to search for the parent, + * grandparent, and higher ancestor certificates. Stops at self-signed + * certificates, or when no ancestor can be found. + *

+ * Thanks to Joe Whitney for helping me put together a Big-O( m * n ) + * implementation where m = the length of the final certificate chain. + * For a while I was using a Big-O( n ^ 2 ) implementation! + * + * @param startingPoint the X509Certificate for which we want to find + * ancestors + * @param certificates A pool of certificates in which we expect to find + * the startingPoint's ancestors. + * @return Array of X509Certificates, starting with the "startingPoint" and + * ending with highest level ancestor we could find in the supplied + * collection. + * @throws java.security.NoSuchAlgorithmException + * on unsupported signature + * algorithms. + * @throws java.security.InvalidKeyException + * on incorrect key. + * @throws java.security.NoSuchProviderException + * if there's no default provider. + * @throws java.security.cert.CertificateException + * on encoding errors. + */ + public static X509Certificate[] buildPath(X509Certificate startingPoint, + Certificate[] certificates) + throws NoSuchAlgorithmException, InvalidKeyException, + NoSuchProviderException, CertificateException { + // Use a LinkedList, because we do lots of random it.remove() operations. + return buildPath(startingPoint, + new LinkedList(Arrays.asList(certificates))); + } + + /** + * Builds the ordered certificate chain upwards from the startingPoint. + * Uses the supplied collection to search for the parent, grandparent, + * and higher ancestor certificates. Stops at self-signed certificates, + * or when no ancestor can be found. + *

+ * Thanks to Joe Whitney for helping me put together a Big-O( m * n ) + * implementation where m = the length of the final certificate chain. + * For a while I was using a Big-O( n ^ 2 ) implementation! + * + * @param startingPoint the X509Certificate for which we want to find + * ancestors + * @param certificates A pool of certificates in which we expect to find + * the startingPoint's ancestors. + * @return Array of X509Certificates, starting with the "startingPoint" and + * ending with highest level ancestor we could find in the supplied + * collection. + * @throws java.security.NoSuchAlgorithmException + * on unsupported signature + * algorithms. + * @throws java.security.InvalidKeyException + * on incorrect key. + * @throws java.security.NoSuchProviderException + * if there's no default provider. + * @throws java.security.cert.CertificateException + * on encoding errors. + */ + public static X509Certificate[] buildPath(X509Certificate startingPoint, + Collection certificates) + throws NoSuchAlgorithmException, InvalidKeyException, + NoSuchProviderException, CertificateException { + LinkedList path = new LinkedList(); + path.add(startingPoint); + boolean nodeAdded = true; + // Keep looping until an iteration happens where we don't add any nodes + // to our path. + while (nodeAdded) { + // We'll start out by assuming nothing gets added. If something + // gets added, then nodeAdded will be changed to "true". + nodeAdded = false; + X509Certificate top = (X509Certificate) path.getLast(); + if (isSelfSigned(top)) { + // We're self-signed, so we're done! + break; + } + + // Not self-signed. Let's see if we're signed by anyone in the + // collection. + Iterator it = certificates.iterator(); + while (it.hasNext()) { + X509Certificate x509 = (X509Certificate) it.next(); + if (verify(top, x509.getPublicKey())) { + // We're signed by this guy! Add him to the chain we're + // building up. + path.add(x509); + nodeAdded = true; + it.remove(); // Not interested in this guy anymore! + break; + } + // Not signed by this guy, let's try the next guy. + } + } + X509Certificate[] results = new X509Certificate[path.size()]; + path.toArray(results); + return results; + } + + public static boolean isSelfSigned(X509Certificate cert) + throws CertificateException, InvalidKeyException, + NoSuchAlgorithmException, NoSuchProviderException { + + return verify(cert, cert.getPublicKey()); + } + + public static boolean verify(X509Certificate cert, PublicKey key) + throws CertificateException, InvalidKeyException, + NoSuchAlgorithmException, NoSuchProviderException { + + String sigAlg = cert.getSigAlgName(); + String keyAlg = key.getAlgorithm(); + sigAlg = sigAlg != null ? sigAlg.trim().toUpperCase() : ""; + keyAlg = keyAlg != null ? keyAlg.trim().toUpperCase() : ""; + if (keyAlg.length() >= 2 && sigAlg.endsWith(keyAlg)) { + try { + cert.verify(key); + return true; + } catch (SignatureException se) { + return false; + } + } else { + return false; + } + } + + public static void main(String[] args) throws Exception { + if (args.length < 2) { + System.out.println("Usage: [special-one] [file-with-certs]"); + System.exit(1); + } + FileInputStream f1 = new FileInputStream(args[0]); + FileInputStream f2 = new FileInputStream(args[1]); + CertificateFactory cf = CertificateFactory.getInstance("X.509"); + X509Certificate theOne = (X509Certificate) cf.generateCertificate(f1); + Collection c = cf.generateCertificates(f2); + + X509Certificate[] path = buildPath(theOne, c); + for (int i = 0; i < path.length; i++) { + System.out.println(Certificates.getCN(path[i])); + } + } +} http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/23c1fd12/3rdparty/not-yet-commons-ssl/src/main/java/org/apache/commons/ssl/asn1/ASN1Choice.java ---------------------------------------------------------------------- diff --git a/3rdparty/not-yet-commons-ssl/src/main/java/org/apache/commons/ssl/asn1/ASN1Choice.java b/3rdparty/not-yet-commons-ssl/src/main/java/org/apache/commons/ssl/asn1/ASN1Choice.java new file mode 100644 index 0000000..c08485e --- /dev/null +++ b/3rdparty/not-yet-commons-ssl/src/main/java/org/apache/commons/ssl/asn1/ASN1Choice.java @@ -0,0 +1,13 @@ +package org.apache.commons.ssl.asn1; + +/** + * Marker interface for CHOICE objects - if you implement this in a role your + * own object any attempt to tag the object implicitly will convert the tag to + * an explicit one as the encoding rules require. + *

+ * If you use this interface your class should also implement the getInstance + * pattern which takes a tag object and the tagging mode used. + */ +public interface ASN1Choice { + // marker interface +} http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/23c1fd12/3rdparty/not-yet-commons-ssl/src/main/java/org/apache/commons/ssl/asn1/ASN1Encodable.java ---------------------------------------------------------------------- diff --git a/3rdparty/not-yet-commons-ssl/src/main/java/org/apache/commons/ssl/asn1/ASN1Encodable.java b/3rdparty/not-yet-commons-ssl/src/main/java/org/apache/commons/ssl/asn1/ASN1Encodable.java new file mode 100644 index 0000000..99900cb --- /dev/null +++ b/3rdparty/not-yet-commons-ssl/src/main/java/org/apache/commons/ssl/asn1/ASN1Encodable.java @@ -0,0 +1,74 @@ +package org.apache.commons.ssl.asn1; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; + +public abstract class ASN1Encodable + implements DEREncodable { + public static final String DER = "DER"; + public static final String BER = "BER"; + + public byte[] getEncoded() + throws IOException { + ByteArrayOutputStream bOut = new ByteArrayOutputStream(); + ASN1OutputStream aOut = new ASN1OutputStream(bOut); + + aOut.writeObject(this); + + return bOut.toByteArray(); + } + + public byte[] getEncoded( + String encoding) + throws IOException { + if (encoding.equals(DER)) { + ByteArrayOutputStream bOut = new ByteArrayOutputStream(); + DEROutputStream dOut = new DEROutputStream(bOut); + + dOut.writeObject(this); + + return bOut.toByteArray(); + } + + return this.getEncoded(); + } + + /** + * Return the DER encoding of the object, null if the DER encoding can not be made. + * + * @return a DER byte array, null otherwise. + */ + public byte[] getDEREncoded() { + try { + return this.getEncoded(DER); + } + catch (IOException e) { + return null; + } + } + + public int hashCode() { + return this.toASN1Object().hashCode(); + } + + public boolean equals( + Object o) { + if (this == o) { + return true; + } + + if (!(o instanceof DEREncodable)) { + return false; + } + + DEREncodable other = (DEREncodable) o; + + return this.toASN1Object().equals(other.getDERObject()); + } + + public DERObject getDERObject() { + return this.toASN1Object(); + } + + public abstract DERObject toASN1Object(); +} http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/23c1fd12/3rdparty/not-yet-commons-ssl/src/main/java/org/apache/commons/ssl/asn1/ASN1EncodableVector.java ---------------------------------------------------------------------- diff --git a/3rdparty/not-yet-commons-ssl/src/main/java/org/apache/commons/ssl/asn1/ASN1EncodableVector.java b/3rdparty/not-yet-commons-ssl/src/main/java/org/apache/commons/ssl/asn1/ASN1EncodableVector.java new file mode 100644 index 0000000..b769758 --- /dev/null +++ b/3rdparty/not-yet-commons-ssl/src/main/java/org/apache/commons/ssl/asn1/ASN1EncodableVector.java @@ -0,0 +1,10 @@ +package org.apache.commons.ssl.asn1; + +/** the parent class for this will eventually disappear. Use this one! */ +public class ASN1EncodableVector + extends DEREncodableVector { + // migrating from DEREncodeableVector + public ASN1EncodableVector() { + + } +} http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/23c1fd12/3rdparty/not-yet-commons-ssl/src/main/java/org/apache/commons/ssl/asn1/ASN1Generator.java ---------------------------------------------------------------------- diff --git a/3rdparty/not-yet-commons-ssl/src/main/java/org/apache/commons/ssl/asn1/ASN1Generator.java b/3rdparty/not-yet-commons-ssl/src/main/java/org/apache/commons/ssl/asn1/ASN1Generator.java new file mode 100644 index 0000000..b39d994 --- /dev/null +++ b/3rdparty/not-yet-commons-ssl/src/main/java/org/apache/commons/ssl/asn1/ASN1Generator.java @@ -0,0 +1,13 @@ +package org.apache.commons.ssl.asn1; + +import java.io.OutputStream; + +public abstract class ASN1Generator { + protected OutputStream _out; + + public ASN1Generator(OutputStream out) { + _out = out; + } + + public abstract OutputStream getRawOutputStream(); +}