WrappedLogSSLSocket.java

  1. /*
  2.  * GovWay - A customizable API Gateway
  3.  * https://govway.org
  4.  *
  5.  * Copyright (c) 2005-2025 Link.it srl (https://link.it).
  6.  *
  7.  * This program is free software: you can redistribute it and/or modify
  8.  * it under the terms of the GNU General Public License version 3, as published by
  9.  * the Free Software Foundation.
  10.  *
  11.  * This program is distributed in the hope that it will be useful,
  12.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14.  * GNU General Public License for more details.
  15.  *
  16.  * You should have received a copy of the GNU General Public License
  17.  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  18.  *
  19.  */


  20. package org.openspcoop2.utils.transport.http;

  21. import java.io.FilterOutputStream;
  22. import java.io.IOException;
  23. import java.io.InputStream;
  24. import java.io.OutputStream;
  25. import java.net.InetAddress;
  26. import java.net.SocketAddress;
  27. import java.net.SocketException;
  28. import java.nio.channels.SocketChannel;
  29. import java.security.cert.Certificate;

  30. import javax.net.ssl.HandshakeCompletedEvent;
  31. import javax.net.ssl.HandshakeCompletedListener;
  32. import javax.net.ssl.SSLParameters;
  33. import javax.net.ssl.SSLSession;
  34. import javax.net.ssl.SSLSocket;

  35. import org.openspcoop2.utils.certificate.CertificateUtils;
  36. import org.openspcoop2.utils.resources.Charset;
  37. import org.slf4j.Logger;

  38. /**
  39.  * WrappedLogSSLSocket
  40.  *
  41.  * @author Poli Andrea (apoli@link.it)
  42.  * @author $Author$
  43.  * @version $Rev$, $Date$
  44.  */
  45. public class WrappedLogSSLSocket extends SSLSocket {

  46.     private SSLSocket delegate;
  47.     private Logger log;
  48.     private String prefixLog;
  49.     private boolean clientCertificateConfigurated;
  50.     private String clientCertificateConfiguratedPath;

  51.     public WrappedLogSSLSocket(SSLSocket s, Logger log, String prefixLog, String clientCertificateConfigurated) {
  52.         this.delegate = s;
  53.         this.log = log;
  54.         this.prefixLog = prefixLog;
  55.         this.clientCertificateConfiguratedPath = clientCertificateConfigurated;
  56.         this.clientCertificateConfigurated = this.clientCertificateConfiguratedPath!=null;
  57.     }

  58.     @Override
  59.     public OutputStream getOutputStream() throws IOException {
  60.         return new WrappedLogOutputStream(this.delegate.getOutputStream(), this.log, this.prefixLog);
  61.     }

  62.     private static class WrappedLogOutputStream extends FilterOutputStream {

  63.         private static final String CHARSET = Charset.UTF_8.getValue();
  64.         private Logger log;
  65.         private String prefixLog;
  66.         private StringBuilder sb;

  67.         public WrappedLogOutputStream(OutputStream out, Logger log, String prefixLog) {
  68.             super(out);
  69.             this.log = log;
  70.             this.prefixLog = prefixLog;
  71.             this.sb = new StringBuilder(this.prefixLog);
  72.         }

  73.         @Override
  74.         public void write(byte[] b, int off, int len)
  75.                 throws IOException {
  76.             this.sb.append(new String(b, off, len, CHARSET));
  77.             this.out.write(b, off, len);
  78.         }

  79.         @Override
  80.         public void write(int b) throws IOException {
  81.             this.sb.append(b);
  82.             this.out.write(b);
  83.         }
  84.        
  85.         @Override
  86.         public void write(byte[] b) throws IOException {
  87.             if(b!=null) {
  88.                 this.sb.append(new String(b));
  89.                 this.out.write(b);
  90.             }
  91.         }

  92.         @Override
  93.         public void close() throws IOException {
  94.             this.log.info(this.sb.toString());
  95.             super.close();
  96.         }
  97.        
  98.         @Override
  99.         public void flush() throws IOException {
  100.             super.flush();
  101.         }
  102.     }
  103.  
  104.     @Override
  105.     public void startHandshake() throws IOException {
  106.         StringBuilder sb = new StringBuilder(this.prefixLog);
  107.         sb.append("startHandshake");
  108.         this.log.info(sb.toString());
  109.         this.delegate.startHandshake();
  110.     }
  111.    
  112.     private WrappedLogHandshakeCompletedListener handshakeCompletedListener = null;
  113.     @Override
  114.     public void addHandshakeCompletedListener(HandshakeCompletedListener listener) {
  115.         this.handshakeCompletedListener = new WrappedLogHandshakeCompletedListener(this, listener);
  116.         this.delegate.addHandshakeCompletedListener(this.handshakeCompletedListener);
  117.     }
  118.     @Override
  119.     public void removeHandshakeCompletedListener(HandshakeCompletedListener listener) {
  120.         this.delegate.removeHandshakeCompletedListener(this.handshakeCompletedListener);
  121.     }
  122.    
  123.     private static class WrappedLogHandshakeCompletedListener implements HandshakeCompletedListener {

  124.         private HandshakeCompletedListener delegate;
  125.         private WrappedLogSSLSocket sslSocket;
  126.         private Logger log;
  127.         private String prefixLog;
  128.         private StringBuilder sb;
  129.         private StringBuilder sbError;
  130.                
  131.         public WrappedLogHandshakeCompletedListener(WrappedLogSSLSocket sslSocket, HandshakeCompletedListener delegate) {
  132.             this.delegate = delegate;
  133.             this.sslSocket = sslSocket;
  134.             this.log = sslSocket.log;
  135.             this.prefixLog = sslSocket.prefixLog;
  136.             this.sb = new StringBuilder(this.prefixLog);
  137.             this.sbError = new StringBuilder(); // prefisso aggiunto dopo
  138.         }
  139.        
  140.         @Override
  141.         public void handshakeCompleted(HandshakeCompletedEvent event) {
  142.             this.delegate.handshakeCompleted(event);
  143.            
  144. //          boolean needClientAuth = this.sslSocket.getNeedClientAuth();
  145. //          boolean useClientMode = this.sslSocket.getUseClientMode();
  146. //          boolean wClientAuth = this.sslSocket.getWantClientAuth();
  147.            
  148.             this.sb.append("handshakeCompleted");
  149.             if(event!=null) {
  150.                
  151.                 if(event.getCipherSuite()!=null) {
  152.                     this.sb.append("\nCipherSuite: "+event.getCipherSuite());
  153.                 }
  154.                
  155.                 if(event.getLocalPrincipal()!=null) {
  156.                     this.sb.append("\nLocalPrincipal: "+event.getLocalPrincipal().getName());
  157.                 }
  158.                 else if(this.sslSocket.clientCertificateConfigurated){
  159.                     this.sbError.append("LocalPrincipal");
  160.                 }
  161.                 if(event.getLocalCertificates()!=null && event.getLocalCertificates().length>0) {
  162.                     this.sb.append("\nLocalCertificates: "+event.getLocalCertificates().length);
  163.                     this.sb.append("\n");
  164.                     print(event.getLocalCertificates(), "LocalCertificate");
  165.                 }
  166.                 else if(this.sslSocket.clientCertificateConfigurated){
  167.                     if(this.sbError.length()>0) {
  168.                         this.sbError.append(",");
  169.                     }
  170.                     this.sbError.append("LocalCertificates");
  171.                 }
  172.                
  173.                 try {
  174.                     if(event.getPeerPrincipal()!=null) {
  175.                         this.sb.append("\nPeerPrincipal: "+event.getPeerPrincipal().getName());
  176.                     }
  177.                 }catch(Exception e) {
  178.                     this.sb.append("\nPeerPrincipal: "+e.getMessage());
  179.                 }
  180.                 try {
  181.                     if(event.getPeerCertificates()!=null && event.getPeerCertificates().length>0) {
  182.                         this.sb.append("\nPeerCertificates: "+event.getPeerCertificates().length);
  183.                         this.sb.append("\n");
  184.                         print(event.getPeerCertificates(), "PeerCertificate");
  185.                     }
  186.                 }catch(Exception e) {
  187.                     this.sb.append("\nPeerCertificates: "+e.getMessage());
  188.                 }
  189.                
  190.             }
  191.            
  192.             this.log.info(this.sb.toString());
  193.             if(this.sbError.length()>0) {
  194.                 this.sbError.append(" non inviato, nonostante sia configurato un certificato client (keystore: "+this.sslSocket.clientCertificateConfiguratedPath+")");
  195.                 this.log.error(this.prefixLog+this.sbError.toString());
  196.             }
  197.         }
  198.        
  199.         private void print(Certificate [] certs, String tipo) {
  200.             for (int j = 0; j < certs.length; j++) {
  201.                 if(certs[j] instanceof java.security.cert.X509Certificate) {
  202.                     java.security.cert.X509Certificate x509 = (java.security.cert.X509Certificate) certs[j];
  203.                     CertificateUtils.printCertificate(this.sb, x509, tipo+"-"+j, true);
  204.                 }
  205.                 else {
  206.                     this.sb.append("#### Certificate["+tipo+"-"+j+"]\n");
  207.                     this.sb.append("Certificate["+tipo+"-"+j+"] non è X509");
  208.                 }
  209.             }
  210.         }
  211.    
  212.     }
  213.    

  214.     @Override
  215.     public boolean getEnableSessionCreation() {
  216.         boolean returnValue = this.delegate.getEnableSessionCreation();
  217.         StringBuilder sb = new StringBuilder(this.prefixLog);
  218.         sb.append("getEnableSessionCreation=").append(returnValue);
  219.         this.log.info(sb.toString());
  220.         return returnValue;
  221.     }

  222.     @Override
  223.     public String[] getEnabledCipherSuites() {
  224.         String[] cipherSuites = this.delegate.getEnabledCipherSuites();
  225.         if(cipherSuites!=null && cipherSuites.length>0) {
  226.             StringBuilder sb = new StringBuilder(this.prefixLog);
  227.             sb.append("EnabledCipherSuites: ");
  228.             for (String cs : cipherSuites) {
  229.                 if(sb.length()>0) {
  230.                     sb.append(",");
  231.                 }
  232.                 sb.append(cs);
  233.             }
  234.             this.log.info(sb.toString());
  235.         }
  236.         return cipherSuites;
  237.     }
  238.    
  239.     @Override
  240.     public String[] getSupportedCipherSuites() {
  241.         String[] cipherSuites = this.delegate.getSupportedCipherSuites();
  242.         if(cipherSuites!=null && cipherSuites.length>0) {
  243.             StringBuilder sb = new StringBuilder(this.prefixLog);
  244.             sb.append("SupportedCipherSuites: ");
  245.             for (String cs : cipherSuites) {
  246.                 if(sb.length()>0) {
  247.                     sb.append(",");
  248.                 }
  249.                 sb.append(cs);
  250.             }
  251.             this.log.info(sb.toString());
  252.         }
  253.         return cipherSuites;
  254.     }

  255.     @Override
  256.     public String[] getEnabledProtocols() {
  257.         String[] enabledProtocols = this.delegate.getEnabledProtocols();
  258.         if(enabledProtocols!=null && enabledProtocols.length>0) {
  259.             StringBuilder sb = new StringBuilder(this.prefixLog);      
  260.             sb.append("EnabledProtocols: ");
  261.             for (String ep : enabledProtocols) {
  262.                 if(sb.length()>0) {
  263.                     sb.append(",");
  264.                 }
  265.                 sb.append(ep);
  266.             }
  267.             this.log.info(sb.toString());
  268.         }
  269.         return enabledProtocols;
  270.     }
  271.    
  272.     @Override
  273.     public String[] getSupportedProtocols() {
  274.         String[] supportedProtocols = this.delegate.getSupportedProtocols();
  275.         if(supportedProtocols!=null && supportedProtocols.length>0) {
  276.             StringBuilder sb = new StringBuilder(this.prefixLog);      
  277.             sb.append("SupportedProtocols: ");
  278.             for (String ep : supportedProtocols) {
  279.                 if(sb.length()>0) {
  280.                     sb.append(",");
  281.                 }
  282.                 sb.append(ep);
  283.             }
  284.             this.log.info(sb.toString());
  285.         }
  286.         return supportedProtocols;
  287.     }

  288.     @Override
  289.     public boolean getNeedClientAuth() {
  290.         boolean returnValue = this.delegate.getNeedClientAuth();
  291.         StringBuilder sb = new StringBuilder(this.prefixLog);
  292.         sb.append("getNeedClientAuth=").append(returnValue);
  293.         this.log.info(sb.toString());
  294.         return returnValue;
  295.     }
  296.    
  297.     @Override
  298.     public boolean getUseClientMode() {
  299.         boolean returnValue = this.delegate.getUseClientMode();
  300.         StringBuilder sb = new StringBuilder(this.prefixLog);
  301.         sb.append("getUseClientMode=").append(returnValue);
  302.         this.log.info(sb.toString());
  303.         return returnValue;
  304.     }
  305.    
  306.     @Override
  307.     public boolean getWantClientAuth() {
  308.         boolean returnValue = this.delegate.getWantClientAuth();
  309.         StringBuilder sb = new StringBuilder(this.prefixLog);
  310.         sb.append("getWantClientAuth=").append(returnValue);
  311.         this.log.info(sb.toString());
  312.         return returnValue;
  313.     }
  314.    
  315.     @Override
  316.     public SSLSession getHandshakeSession() {
  317.         return this.delegate.getHandshakeSession();
  318.     }

  319.     @Override
  320.     public SSLParameters getSSLParameters() {
  321.         return this.delegate.getSSLParameters();
  322.     }

  323.     @Override
  324.     public SSLSession getSession() {
  325.         return this.delegate.getSession();
  326.     }

  327.     @Override
  328.     public void setEnableSessionCreation(boolean flag) {
  329.         this.delegate.setEnableSessionCreation(flag);
  330.     }

  331.     @Override
  332.     public void setEnabledCipherSuites(String[] suites) {
  333.         this.delegate.setEnabledCipherSuites(suites);
  334.     }

  335.     @Override
  336.     public void setEnabledProtocols(String[] protocols) {
  337.         this.delegate.setEnabledProtocols(protocols);
  338.     }

  339.     @Override
  340.     public void setNeedClientAuth(boolean need) {
  341.         this.delegate.setNeedClientAuth(need);
  342.     }

  343.     @Override
  344.     public void setSSLParameters(SSLParameters params) {
  345.         this.delegate.setSSLParameters(params);
  346.     }

  347.     @Override
  348.     public void setUseClientMode(boolean mode) {
  349.         this.delegate.setUseClientMode(mode);
  350.     }

  351.     @Override
  352.     public void setWantClientAuth(boolean want) {
  353.         this.delegate.setWantClientAuth(want);
  354.     }

  355.     // METODI NON MODIFICATI
  356.    
  357.     @Override
  358.     public void connect(SocketAddress endpoint) throws IOException {
  359.         this.delegate.connect(endpoint);
  360.     }

  361.     @Override
  362.     public void connect(SocketAddress endpoint, int timeout) throws IOException {
  363.         this.delegate.connect(endpoint, timeout);
  364.     }

  365.     @Override
  366.     public void bind(SocketAddress bindpoint) throws IOException {
  367.         this.delegate.bind(bindpoint);
  368.     }

  369.     @Override
  370.     public InetAddress getInetAddress() {
  371.         return this.delegate.getInetAddress();
  372.     }

  373.     @Override
  374.     public InetAddress getLocalAddress() {
  375.         return this.delegate.getLocalAddress();
  376.     }

  377.     @Override
  378.     public int getPort() {
  379.         return this.delegate.getPort();
  380.     }

  381.     @Override
  382.     public int getLocalPort() {
  383.         return this.delegate.getLocalPort();
  384.     }

  385.     @Override
  386.     public SocketAddress getRemoteSocketAddress() {
  387.         return this.delegate.getRemoteSocketAddress();
  388.     }

  389.     @Override
  390.     public SocketAddress getLocalSocketAddress() {
  391.         return this.delegate.getLocalSocketAddress();
  392.     }

  393.     @Override
  394.     public SocketChannel getChannel() {
  395.         return this.delegate.getChannel();
  396.     }

  397.     @Override
  398.     public InputStream getInputStream() throws IOException {
  399.         return this.delegate.getInputStream();
  400.     }

  401.     @Override
  402.     public void setTcpNoDelay(boolean on) throws SocketException {
  403.         this.delegate.setTcpNoDelay(on);
  404.     }

  405.     @Override
  406.     public boolean getTcpNoDelay() throws SocketException {
  407.         return this.delegate.getTcpNoDelay();
  408.     }

  409.     @Override
  410.     public void setSoLinger(boolean on, int linger) throws SocketException {
  411.         this.delegate.setSoLinger(on, linger);
  412.     }

  413.     @Override
  414.     public int getSoLinger() throws SocketException {
  415.         return this.delegate.getSoLinger();
  416.     }

  417.     @Override
  418.     public void sendUrgentData(int data) throws IOException {
  419.         this.delegate.sendUrgentData(data);
  420.     }

  421.     @Override
  422.     public void setOOBInline(boolean on) throws SocketException {
  423.         this.delegate.setOOBInline(on);
  424.     }

  425.     @Override
  426.     public boolean getOOBInline() throws SocketException {
  427.         return this.delegate.getOOBInline();
  428.     }

  429.     @Override
  430.     public synchronized void setSoTimeout(int timeout) throws SocketException {
  431.         this.delegate.setSoTimeout(timeout);
  432.     }

  433.     @Override
  434.     public synchronized int getSoTimeout() throws SocketException {
  435.         return this.delegate.getSoTimeout();
  436.     }

  437.     @Override
  438.     public synchronized void setSendBufferSize(int size) throws SocketException {
  439.         this.delegate.setSendBufferSize(size);
  440.     }

  441.     @Override
  442.     public synchronized int getSendBufferSize() throws SocketException {
  443.         return this.delegate.getSendBufferSize();
  444.     }

  445.     @Override
  446.     public synchronized void setReceiveBufferSize(int size) throws SocketException {
  447.         this.delegate.setReceiveBufferSize(size);
  448.     }

  449.     @Override
  450.     public synchronized int getReceiveBufferSize() throws SocketException {
  451.         return this.delegate.getReceiveBufferSize();
  452.     }

  453.     @Override
  454.     public void setKeepAlive(boolean on) throws SocketException {
  455.         this.delegate.setKeepAlive(on);
  456.     }

  457.     @Override
  458.     public boolean getKeepAlive() throws SocketException {
  459.         return this.delegate.getKeepAlive();
  460.     }

  461.     @Override
  462.     public void setTrafficClass(int tc) throws SocketException {
  463.         this.delegate.setTrafficClass(tc);
  464.     }

  465.     @Override
  466.     public int getTrafficClass() throws SocketException {
  467.         return this.delegate.getTrafficClass();
  468.     }

  469.     @Override
  470.     public void setReuseAddress(boolean on) throws SocketException {
  471.         this.delegate.setReuseAddress(on);
  472.     }

  473.     @Override
  474.     public boolean getReuseAddress() throws SocketException {
  475.         return this.delegate.getReuseAddress();
  476.     }

  477.     @Override
  478.     public synchronized void close() throws IOException {
  479.         this.delegate.close();
  480.     }

  481.     @Override
  482.     public void shutdownInput() throws IOException {
  483.         this.delegate.shutdownInput();
  484.     }

  485.     @Override
  486.     public void shutdownOutput() throws IOException {
  487.         this.delegate.shutdownOutput();
  488.     }

  489.     @Override
  490.     public String toString() {
  491.         return this.delegate.toString();
  492.     }

  493.     @Override
  494.     public boolean isConnected() {
  495.         return this.delegate.isConnected();
  496.     }

  497.     @Override
  498.     public boolean isBound() {
  499.         return this.delegate.isBound();
  500.     }

  501.     @Override
  502.     public boolean isClosed() {
  503.         return this.delegate.isClosed();
  504.     }

  505.     @Override
  506.     public boolean isInputShutdown() {
  507.         return this.delegate.isInputShutdown();
  508.     }

  509.     @Override
  510.     public boolean isOutputShutdown() {
  511.         return this.delegate.isOutputShutdown();
  512.     }

  513.     @Override
  514.     public void setPerformancePreferences(int connectionTime, int latency, int bandwidth) {
  515.         this.delegate.setPerformancePreferences(connectionTime, latency, bandwidth);
  516.     }

  517.     @Override
  518.     public int hashCode() {
  519.         return this.delegate.hashCode();
  520.     }

  521.     @Override
  522.     public boolean equals(Object obj) {
  523.         return this.delegate.equals(obj);
  524.     }
  525. }