
org.jwall.web.audit.net.AuditEventMLogcReceiver 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.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.io.StringReader;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.URL;
import java.security.KeyStore;
import java.util.Collection;
import javax.net.ssl.KeyManager;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLServerSocketFactory;
import org.jwall.web.audit.AuditEvent;
import org.jwall.web.audit.AuditEventListener;
import org.jwall.web.audit.io.AuditEventWriter;
import org.jwall.web.audit.io.ModSecurity2AuditReader;
import org.jwall.web.audit.io.ModSecurity2AuditWriter;
import org.jwall.web.audit.util.Base64Codec;
import org.jwall.web.http.HttpHeader;
/**
*
* This class implements a simple SSL based server component for receiving ModSecurity
* audit events from the mlogc application.
*
*
* @author Christian Bockermann <[email protected]>
*
*/
public class AuditEventMLogcReceiver
extends Thread
implements AuditEventListener
{
ServerSocket socket;
AuditEventWriter writer;
/**
* Create a new instance of this class. The instance will register itself to
* all its forked client handlers, thus it will receive all events
*
* @throws Exception
*/
public AuditEventMLogcReceiver() throws Exception {
URL url = AuditEventMLogcReceiver.class.getResource( "/org/jwall/web/audit/net/keystore" );
System.out.println( "using certificate @ " + url );
InputStream keystream = url.openStream();
char[] passphrase = "geheim".toCharArray();
KeyStore keystore = KeyStore.getInstance("JKS");
keystore.load( keystream, passphrase );
// Now we initialize a KeyManagerFactory with the KeyStore
KeyManagerFactory kmf =
KeyManagerFactory.getInstance("SunX509");
kmf.init(keystore, passphrase);
// Now we create an SSLContext and initialize it with
// KeyManagers from the KeyManagerFactory
SSLContext context = SSLContext.getInstance("TLS");
KeyManager[] keyManagers = kmf.getKeyManagers();
context.init(keyManagers, null, null);
// First we need a SocketFactory that will create
// SSL server sockets.
SSLServerSocketFactory ssf = context.getServerSocketFactory();
socket = ssf.createServerSocket( 8886 );
//socket = new ServerSocket( 8886, 10, InetAddress.getByName( "127.0.0.1" ) );
System.out.println( "Starting MLogc, listening at " + socket.getInetAddress().getHostAddress() + ":" + socket.getLocalPort() );
writer = new ModSecurity2AuditWriter( new File( "/tmp/receiver-test-audit.log") );
}
public void run(){
while( true ){
try {
Socket client = socket.accept();
System.out.println( "new mlogc-connection!" );
AuditEventSocketReader reader = new AuditEventSocketReader( client, this );
reader.start();
} catch (Exception e) {
e.printStackTrace();
}
}
}
public void eventArrived( String sensorId, AuditEvent evt ){
eventArrived( evt );
}
public void eventArrived( AuditEvent evt ){
try {
System.out.println( "ScriptEvent arrived!" );
writer.writeEvent( evt );
} catch (Exception e) {
e.printStackTrace();
}
}
public void eventsArrived( Collection evts ){
for( AuditEvent evt : evts )
eventArrived( evt );
}
class AuditEventSocketReader extends Thread {
Socket sock;
InputStream in;
AuditEventMLogcReceiver listener;
BufferedReader reader;
PrintStream out;
public AuditEventSocketReader( Socket socket, AuditEventMLogcReceiver listener ) throws IOException {
sock = socket;
in = sock.getInputStream();
this.listener = listener;
reader = new BufferedReader( new InputStreamReader( in ) );
out = new PrintStream( sock.getOutputStream() );
}
public AuditEvent readEvent(){
try {
// read the header
//
StringBuffer header = new StringBuffer();
int contentLength = 0;
String sensorId = null;
String line = reader.readLine();
if( line == null )
return null;
while( line != null && !line.trim().equals("") ){
System.out.println( "line: " + line );
header.append( line + "\n" );
//
// check for the content length of the event received
//
if( line.toLowerCase().startsWith( "content-length: " ) ){
contentLength = Integer.parseInt( line.substring( "content-length: ".length() ) );
System.out.println( "Found content length: " + contentLength );
}
if( line.toLowerCase().startsWith("authentication:") ){
//
// extract the sensor-id and check the password
//
String[] t = line.substring( "authentication".length() ).split( " " );
Base64Codec codec = new Base64Codec();
String userpass = new String( codec.decode( t[1].getBytes() ) );
int k = 0;
for(int i = userpass.length() - 1; i >= 0; i--)
if(userpass.charAt(i) == ':'){
k = i;
i = -1;
}
sensorId = userpass.substring( 0, k );
}
line = reader.readLine();
}
header.append("\n");
System.out.println("Header:\n" + header.toString() );
StringBuffer eventData = new StringBuffer();
while( contentLength > 0 ){
eventData.append( (char) reader.read() );
contentLength--;
//System.out.println("Content: " + contentLength + " bytes remaining..." );
}
System.out.println( "ScriptEvent:\n" + eventData );
ModSecurity2AuditReader reader = new ModSecurity2AuditReader( new StringReader( eventData.toString() ) );
AuditEvent evt = reader.readNext();
if( evt != null ){
System.out.println( "Sending 200 OK");
out.print( "HTTP/1.1 200 OK" + HttpHeader.CRLF );
} else {
System.out.println( "Sending 500 Error");
out.print( "HTTP/1.1 500 Error" + HttpHeader.CRLF );
}
out.print( "X-Server: jwall.org AuditEventMLogcReceiver" + HttpHeader.CRLF );
out.print( "Content-Length: 0" + HttpHeader.CRLF );
out.print( "Content-Type: text/plain" + HttpHeader.CRLF );
out.print( HttpHeader.CRLF + HttpHeader.CRLF );
out.flush();
listener.eventArrived( sensorId, evt );
return evt;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
public void run(){
try {
while( true ) {
AuditEvent evt = readEvent();
while( evt == null ){
try {
System.out.println("Sleeping..." );
Thread.sleep( 1000 );
} catch (Exception e) {}
evt = readEvent();
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
/**
* @param args
*/
public static void main(String[] args)
{
try {
AuditEventMLogcReceiver receiver = new AuditEventMLogcReceiver();
receiver.start();
} catch (Exception e) {
e.printStackTrace();
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy