All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.jwall.web.audit.net.AuditEventConsoleSender Maven / Gradle / Ivy

/*
 *  Copyright (C) 2007-2014 Christian Bockermann 
 *
 *  This file is part of the  web-audit  library.
 *
 *  web-audit library is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  The  web-audit  library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program.  If not, see .
 *
 */
package org.jwall.web.audit.net;


import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.net.Socket;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.Collection;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;

import org.jwall.Collector;
import org.jwall.web.audit.AuditEvent;
import org.jwall.web.audit.AuditEventListener;
import org.jwall.web.audit.io.ConcurrentAuditWriter;
import org.jwall.web.audit.util.Base64Codec;
import org.jwall.web.audit.util.MD5;


/**
 * 
 * This class implements a simple socket-handler which provides easy
 * injection of audit-events to the modsecurity-console.
 * 
 * @author Christian Bockermann <[email protected]>
 *
 */
public class AuditEventConsoleSender 
implements AuditEventListener
{
    public final static String CONSOLE_HOST = "org.modsecurity.console.host";
    public final static String CONSOLE_PORT = "org.modsecurity.console.port";
    public final static String CONSOLE_USER = "org.modsecurity.console.user";
    public final static String CONSOLE_PASS = "org.modsecurity.console.password";
    public final static String CONSOLE_CONNECTION_KEEP_ALIVE = "org.modsecurity.collector.keep-alive";
    public final static String CONSOLE_CONNECTION_SSL = "org.modsecurity.collector.ssl-enabled";

    /** A unique logger for this class */
    private static Logger log = LoggerFactory.getLogger( "AuditEventConsoleSender" );

    /** the uri of the receiver servlet */
    public final static String CONSOLE_URI = "/rpc/auditLogReceiver";

    /** the destination host */
    private String host = "localhost";

    /** the port to which this senders connects */
    private int port = 8888;

    /** the user name for authentication */
    private String user = "";

    /** the password used for authentication */
    private String pass = "";


    private Socket socket = null;

    /**
     * 
     * This method creates a new console sender that sends all arriving
     * events to the given host host using login
     * and password for authentifaction.
     * 
     * @param host The host on which the Console is running.
     * @param port The port, at which the Console is listening.
     * @param login User-name for authentication with the console.
     * @param password Password for authentication.
     * 
     */
    public AuditEventConsoleSender( String host, int port, String login, String password)
    {
        this.host = host;
        this.port = port;
        this.user = login;
        this.pass = password;

        try {
            log.debug( "Disabling certificate validation..." );
            SSLContext sc = SSLContext.getInstance( "SSL" );
            sc.init( null, new TrustManager[]{ new ZeroTrustManager() }, new java.security.SecureRandom() );
            HttpsURLConnection.setDefaultSSLSocketFactory( sc.getSocketFactory() );
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    /**
     * This method sends the given audit-event to the configured console.
     * 
     * @param evt The event to be sent to the console.
     * @throws Exception In case an error occurs.
     */
    public void sendAuditEvent( AuditEvent evt ) throws Exception {

        byte[] data = evt.toString().getBytes();
        String hash = "md5:"+MD5.md5( data );

        String sum = ConcurrentAuditWriter.createSummary( evt );
        Base64Codec codec = new Base64Codec();
        String cred = new String( codec.encode( ( user + ":" + pass ).getBytes() ) );
        String ua = "jwall.org/Collector Version " + Collector.VERSION; 
        Socket sock = this.getSocketConnection();

        try {
            
            StringBuffer request = new StringBuffer();
            
            request.append("PUT " + Collector.p.getProperty( AuditEventConsoleSender.CONSOLE_URI ) + " HTTP/1.1\r\n" );
            request.append( "Authorization: Basic " + cred + "\r\n" );
            request.append( "Host: " + host );
            
            if( this.port != 80 )
                request.append( ":" + port );
            
            request.append( "\r\n" );
            
            request.append( "X-Content-Hash: " + hash + "\r\n" );
            request.append( "X-ForensicLog-Summary: " + sum + "\r\n" );
            request.append( "User-Agent: " + ua + "\r\n" );
            
            if( "true".equalsIgnoreCase( Collector.getProperty( CONSOLE_CONNECTION_KEEP_ALIVE ) ) ) 
                request.append( "Connection: keep-alive\r\n" );
            
            request.append( "Content-Length: " + data.length + "\r\n" );
            request.append( "\r\n" );
            
            //log.info("Sending request header:\n" + request.toString() );
            
            PrintStream out = new PrintStream( sock.getOutputStream() );
            out.print( request.toString() );
            
            log.debug( "Writing " + data.length + " bytes of data to server..." );
            out.write( data );
            out.flush();
            
        } catch (Exception e) {
            e.printStackTrace();
            sock = null;
            return;
        }
        
        
        BufferedReader r = new BufferedReader( new InputStreamReader( sock.getInputStream() ) );
        String line = r.readLine();
        if( line != null ){
            
            if( line.toLowerCase().indexOf( "200 ok" ) >= 0 )
                log.debug( "Server accepted event." );
            else 
                log.debug( "Response-line: " + line );
        }
        
        while( line != null && ! "".equals( line.trim() ) ){
            log.debug( "RESPONSE: " + line );
            line = r.readLine();
        }
        r.close();
            

        /*
        InputStream in = sock.getInputStream();
        int avail = in.available();
        while( avail > 0 ){
            byte[] bytes = new byte[avail];
            log.info( "Consuming " + avail + " bytes of response..." );
            in.read( bytes );
            avail = in.available();
        }
         */
        
        if( "true".equalsIgnoreCase( Collector.getProperty( CONSOLE_CONNECTION_KEEP_ALIVE ) ) ) {
            return;
        } else {
            
            closeSocketConnection();
            
        }
    }


    public Socket getSocketConnection() throws Exception {

        if( socket != null && !socket.isClosed() )
            return socket;

        log.debug( "Establishing socket connection");
        
        String ssl = Collector.getProperty( CONSOLE_CONNECTION_SSL );
        
        if( ssl != null && !"false".equalsIgnoreCase( ssl ) ){ //port == 8888 || port == 8889 ){

            log.debug("Creating new ssl-enabled socket to " + host + ":" + port );
            
            // using secure https connection
            //
            SSLContext context = SSLContext.getInstance("TLS"); 
            TrustManager[] trustManagers = new TrustManager[]{ new ZeroTrustManager() }; 
            context.init(null, trustManagers, null); 

            SSLSocketFactory sf = context.getSocketFactory();  
            socket = sf.createSocket( host, port );

        } else {
            
            log.debug( "Creating new plain-http socket to " + host + ":" + port );
            socket = new Socket( host, port );
        }

        return socket;
    }

    
    public void closeSocketConnection() throws Exception {
        
        if( socket != null && !socket.isClosed() )
            socket.close();
        
        socket = null;
    }

    /**
     * 
     * Simply send all arriving events to the configured console. 
     * 
     */
    public void eventArrived( AuditEvent evt ){

        try {

            this.sendAuditEvent( evt );

        } catch ( Exception e ) {

            e.printStackTrace();

        }
    }
    
    public void eventsArrived( Collection events ){
        for( AuditEvent evt: events )
            eventArrived( evt );
    }


    public class ZeroTrustManager 
    implements X509TrustManager, TrustManager 
    {
        private Logger log = LoggerFactory.getLogger( "ZeroTrustManager" );

        public void checkClientTrusted(X509Certificate[] chain, String authType)
        throws CertificateException {

            log.debug( "checkClientTrusted: \n");

            for( X509Certificate cert : chain ){
                log.debug("-------------------------------------------------------");
                log.debug( " SubjectDN = "+cert.getSubjectDN() );
                log.debug( " Issuer = " + cert.getIssuerDN() );
            }       
        }

        public void checkServerTrusted(X509Certificate[] chain, String authType)
        throws CertificateException {

            log.debug( "checkServerTrusted: \n");

            for( X509Certificate cert : chain ){
                log.debug("-------------------------------------------------------");
                log.debug( " SubjectDN = "+cert.getSubjectDN() );
                log.debug( " Issuer = " + cert.getIssuerDN() );
            }       
        }

        public X509Certificate[] getAcceptedIssuers() {
            return null;
        }
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy