From 2ccef1c93d4c1a478fbdd8a49caf0735f68ba141 Mon Sep 17 00:00:00 2001 From: Michael Stahl Date: Thu, 8 Oct 2015 21:51:40 +0200 Subject: swext: add a logging out stream to help debugging TLS connections Change-Id: Idbabae3edad5e95a37fa9834d24a72ebd13087ae --- swext/mediawiki/src/com/sun/star/wiki/Helper.java | 3 + .../sun/star/wiki/WikiProtocolSocketFactory.java | 164 +++++++++++++++++++++ 2 files changed, 167 insertions(+) (limited to 'swext/mediawiki') diff --git a/swext/mediawiki/src/com/sun/star/wiki/Helper.java b/swext/mediawiki/src/com/sun/star/wiki/Helper.java index f5e5c4848bc8..b40b5f107d7d 100644 --- a/swext/mediawiki/src/com/sun/star/wiki/Helper.java +++ b/swext/mediawiki/src/com/sun/star/wiki/Helper.java @@ -639,6 +639,9 @@ public class Helper ((HttpsURLConnection) conn).setSSLSocketFactory(new WikiProtocolSocketFactory()); } +// enable this to help debug connections where TLS gets in the way +// ((HttpsURLConnection) conn).setSSLSocketFactory(new LoggingProtocolSocketFactory()); + conn.setRequestMethod(method); // note: don't connect yet so that the caller can do some further setup diff --git a/swext/mediawiki/src/com/sun/star/wiki/WikiProtocolSocketFactory.java b/swext/mediawiki/src/com/sun/star/wiki/WikiProtocolSocketFactory.java index 5d7efe1cebf2..3d2d22dab61f 100644 --- a/swext/mediawiki/src/com/sun/star/wiki/WikiProtocolSocketFactory.java +++ b/swext/mediawiki/src/com/sun/star/wiki/WikiProtocolSocketFactory.java @@ -25,6 +25,7 @@ import java.net.Socket; import java.net.UnknownHostException; import java.security.KeyStore; import javax.net.ssl.SSLContext; +import javax.net.ssl.SSLSocket; import javax.net.ssl.SSLSocketFactory; import javax.net.ssl.TrustManager; import javax.net.ssl.TrustManagerFactory; @@ -167,3 +168,166 @@ class WikiProtocolSocketFactory extends SSLSocketFactory } } +// A factory that creates streams that log everything that's written +// to stderr - useful for debugging encrypted TLS connections +class LoggingProtocolSocketFactory extends SSLSocketFactory +{ + private SSLContext m_aSSLContext; + + private static class LogSocket extends SSLSocket + { + private SSLSocket m_Socket; + + public LogSocket(Socket socket) + { + m_Socket = (SSLSocket) socket; + } + + private static class LogStream extends java.io.FilterOutputStream + { + public LogStream(java.io.OutputStream stream) + { + super(stream); + } + + @Override + public void write(byte[] buf, int offset, int len) + throws IOException + { + System.err.println("LogStream.write: \"" + new String(buf, offset, len, "UTF-8") + "\""); + out.write(buf, offset, len); + } + } + + @Override + public java.io.OutputStream getOutputStream() throws IOException + { + return new LogStream(m_Socket.getOutputStream()); + } + + @Override public void addHandshakeCompletedListener(javax.net.ssl.HandshakeCompletedListener listener) { m_Socket.addHandshakeCompletedListener(listener); } + @Override public String[] getEnabledCipherSuites() { return m_Socket.getEnabledCipherSuites(); } + @Override public String[] getEnabledProtocols() { return m_Socket.getEnabledProtocols(); } + @Override public boolean getEnableSessionCreation() { return m_Socket.getEnableSessionCreation(); } + @Override public boolean getNeedClientAuth() { return m_Socket.getNeedClientAuth(); } + @Override public javax.net.ssl.SSLSession getSession() { return m_Socket.getSession(); } + @Override public javax.net.ssl.SSLParameters getSSLParameters() { return m_Socket.getSSLParameters(); } + @Override public String[] getSupportedCipherSuites() { return m_Socket.getSupportedCipherSuites(); } + @Override public String[] getSupportedProtocols() { return m_Socket.getSupportedProtocols(); } + @Override public boolean getUseClientMode() { return m_Socket.getUseClientMode(); } + @Override public boolean getWantClientAuth() { return m_Socket.getWantClientAuth(); } + @Override public void removeHandshakeCompletedListener(javax.net.ssl.HandshakeCompletedListener listener) { m_Socket.removeHandshakeCompletedListener(listener); } + @Override public void setEnabledCipherSuites(String[] suites) { m_Socket.setEnabledCipherSuites(suites); } + @Override public void setEnabledProtocols(String[] protocols) { m_Socket.setEnabledProtocols(protocols); } + @Override public void setEnableSessionCreation(boolean flag) { m_Socket.setEnableSessionCreation(flag); } + @Override public void setNeedClientAuth(boolean need) { m_Socket.setNeedClientAuth(need); } + @Override public void setSSLParameters(javax.net.ssl.SSLParameters params) { m_Socket.setSSLParameters(params); } + @Override public void setUseClientMode(boolean mode) { m_Socket.setUseClientMode(mode); } + @Override public void setWantClientAuth(boolean want) { m_Socket.setWantClientAuth(want); } + @Override public void startHandshake() throws IOException { m_Socket.startHandshake(); } + + @Override public void bind(java.net.SocketAddress bindpoint) throws IOException { m_Socket.bind(bindpoint); } + @Override public void close() throws IOException { m_Socket.close(); } + @Override public void connect(java.net.SocketAddress endpoint) throws IOException { m_Socket.connect(endpoint); } + @Override public void connect(java.net.SocketAddress endpoint, int timeout) throws IOException { m_Socket.connect(endpoint, timeout); } + @Override public java.nio.channels.SocketChannel getChannel() { return m_Socket.getChannel(); } + @Override public InetAddress getInetAddress() { return m_Socket.getInetAddress(); } + @Override public java.io.InputStream getInputStream() throws IOException { return m_Socket.getInputStream(); } + @Override public boolean getKeepAlive() throws java.net.SocketException { return m_Socket.getKeepAlive(); } + @Override public InetAddress getLocalAddress() { return m_Socket.getLocalAddress(); } + @Override public int getLocalPort() { return m_Socket.getLocalPort(); } + @Override public java.net.SocketAddress getLocalSocketAddress() { return m_Socket.getLocalSocketAddress(); } + @Override public boolean getOOBInline() throws java.net.SocketException { return m_Socket.getOOBInline(); } + @Override public int getPort() { return m_Socket.getPort(); } + @Override public int getReceiveBufferSize() throws java.net.SocketException { return m_Socket.getReceiveBufferSize(); } + @Override public java.net.SocketAddress getRemoteSocketAddress() { return m_Socket.getRemoteSocketAddress(); } + @Override public boolean getReuseAddress() throws java.net.SocketException { return m_Socket.getReuseAddress(); } + @Override public int getSendBufferSize() throws java.net.SocketException { return m_Socket.getSendBufferSize(); } + @Override public int getSoLinger() throws java.net.SocketException { return m_Socket.getSoLinger(); } + @Override public int getSoTimeout() throws java.net.SocketException { return m_Socket.getSoTimeout(); } + @Override public boolean getTcpNoDelay() throws java.net.SocketException { return m_Socket.getTcpNoDelay(); } + @Override public int getTrafficClass() throws java.net.SocketException { return m_Socket.getTrafficClass(); } + @Override public boolean isBound() { return m_Socket.isBound(); } + @Override public boolean isClosed() { return m_Socket.isClosed(); } + @Override public boolean isConnected() { return m_Socket.isConnected(); } + @Override public boolean isInputShutdown() { return m_Socket.isInputShutdown(); } + @Override public boolean isOutputShutdown() { return m_Socket.isOutputShutdown(); } + @Override public void sendUrgentData(int data) throws IOException { m_Socket.sendUrgentData(data); } + @Override public void setKeepAlive(boolean on) throws java.net.SocketException { m_Socket.setKeepAlive(on); } + @Override public void setOOBInline(boolean on) throws java.net.SocketException { m_Socket.setOOBInline(on); } + @Override public void setPerformancePreferences(int connectionTime, int latency, int bandwidth) { m_Socket.setPerformancePreferences(connectionTime, latency, bandwidth); } + @Override public void setReceiveBufferSize(int size) throws java.net.SocketException { m_Socket.setReceiveBufferSize(size); } + @Override public void setReuseAddress(boolean on) throws java.net.SocketException { m_Socket.setReuseAddress(on); } + @Override public void setSendBufferSize(int size) throws java.net.SocketException { m_Socket.setSendBufferSize(size); } + @Override public void setSoLinger(boolean on, int linger) throws java.net.SocketException { m_Socket.setSoLinger(on, linger); } + @Override public void setSoTimeout(int timeout) throws java.net.SocketException{ m_Socket.setSoTimeout(timeout); } + @Override public void setTcpNoDelay(boolean on) throws java.net.SocketException{ m_Socket.setTcpNoDelay(on); } + @Override public void setTrafficClass(int tc) throws java.net.SocketException { m_Socket.setTrafficClass(tc); } + @Override public void shutdownInput() throws IOException { m_Socket.shutdownInput(); } + @Override public void shutdownOutput() throws IOException { m_Socket.shutdownOutput(); } + @Override public String toString() { return m_Socket.toString(); } + + } + + @Override + public Socket createSocket(InetAddress address, int port) + throws IOException + { + return new LogSocket(((SSLSocketFactory) SSLSocketFactory.getDefault()).createSocket(address, port)); + } + + @Override + public Socket createSocket(InetAddress address, int port, InetAddress localAddress, int localPort) + throws IOException + { + return new LogSocket(((SSLSocketFactory) SSLSocketFactory.getDefault()).createSocket(address, port, localAddress, localPort)); + } + + @Override + public Socket createSocket( String sHost, int nPort, InetAddress clientHost, int clientPort ) + throws IOException, UnknownHostException + { + return new LogSocket(((SSLSocketFactory) SSLSocketFactory.getDefault()).createSocket(sHost, nPort, clientHost, clientPort)); + } + + @Override + public Socket createSocket( String sHost, int nPort ) + throws IOException, UnknownHostException + { + return new LogSocket(((SSLSocketFactory) SSLSocketFactory.getDefault()).createSocket(sHost, nPort)); + } + + @Override + public Socket createSocket( Socket aSocket, String sHost, int nPort, boolean bAutoClose ) + throws IOException + { + return new LogSocket(((SSLSocketFactory) SSLSocketFactory.getDefault()).createSocket(aSocket, sHost, nPort, bAutoClose)); + } + + @Override + public String[] getDefaultCipherSuites() + { + // have to implement abstract method, just use the default + return ((SSLSocketFactory) SSLSocketFactory.getDefault()).getDefaultCipherSuites(); + } + + @Override + public String[] getSupportedCipherSuites() + { + // have to implement abstract method, just use the default + return ((SSLSocketFactory) SSLSocketFactory.getDefault()).getSupportedCipherSuites(); + } + + @Override + public boolean equals(Object obj) + { + return ((obj != null) && obj.getClass().equals(LoggingProtocolSocketFactory.class)); + } + + @Override + public int hashCode() + { + return LoggingProtocolSocketFactory.class.hashCode(); + } +} + -- cgit