/*
* Copyright (C) 2007-2014 Christian Bockermann <chris@jwall.org>
*
* 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 <http://www.gnu.org/licenses/>.
*
*/
package org.jwall;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Properties;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.jwall.web.audit.AuditEventDispatcher;
import org.jwall.web.audit.ModSecurityAuditEvent;
import org.jwall.web.audit.io.AccessLogAuditReader;
import org.jwall.web.audit.io.AuditEventReader;
import org.jwall.web.audit.io.AuditFormat;
import org.jwall.web.audit.io.ConcurrentAuditReader;
import org.jwall.web.audit.io.ModSecurity2AuditReader;
import org.jwall.web.audit.io.ModSecurityAuditReader;
import org.jwall.web.audit.net.NetworkEventServer;
import org.jwall.web.audit.util.Authenticator;
import org.jwall.web.audit.util.SimplePasswordAuthenticator;
/**
*
* This class encapsulates the AuditEvent server. It starts a server-process, listening
* for incoming ssl-connections on the specified port (default port is 10001). This is
* all handled by the <code>org.jwall.audit.net.NetworkEventServer</code> class.
*
* This class mainly parses the config and commandline settings and starts the basic
* server-thread.
*
* @author Christian Bockermann <chris@jwall.org>
*
*/
public class AuditServer
{
public final static String VERSION = "v0.1";
private static SimpleDateFormat LOG_DATE = ModSecurityAuditEvent.fmt;
private static Logger log = LoggerFactory.getLogger( "AuditServer" );
public static void main(String args[]){
try {
File auditFile = null;
int port = 10001;
long skip = 0;
Authenticator auth = null;
if(args.length == 0){
printUsage();
System.exit(-1);
}
for(int i = 0; i < args.length; i++){
if(args[i].startsWith("-v") || args[i].startsWith("--v") ){
System.out.println("AuditServer, Version " + VERSION );
System.exit(0);
}
if(args[i].equals("-h") || args[i].startsWith("--h") || args[i].equals("-?")){
printUsage();
System.exit(0);
}
if(args[i].equals("--audit-file") && i+1 < args.length){
auditFile = new File(args[i+1]);
if((!auditFile.exists()) || (!auditFile.canRead())){
log.warn("Cannot read audit-data from: "+auditFile.getAbsolutePath());
System.exit(-1);
}
}
if((args[i].startsWith("--server-port") || args[i].equals("--port")) && i+1 < args.length){
try {
port = Integer.parseInt(args[i+1]);
} catch (Exception e) {
log.warn("Invalid port: "+e.getMessage());
System.exit(-1);
}
}
if((args[i].startsWith("--server-users") || args[i].startsWith("--users")) && i+1 < args.length){
try {
if( auth != null ){
throw new Exception("Authentication already specified!");
}
Properties users = new Properties();
users.load( new FileInputStream(new File(args[i+1])) );
Properties groups = new Properties();
log.info("Using file-authentication, "+users.keySet().size()+" users loaded.");
if( users.keySet().size() == 0 )
users.put("admin", "sercet");
auth = new SimplePasswordAuthenticator( users, groups );
} catch (Exception pe) {
pe.printStackTrace();
log.warn("Could not read password-file for user authentication!");
System.exit(-1);
}
}
}
if(auditFile == null){
log.warn("\nAn audit-file needs to be provided. Use:\n --audit-file <file>\n");
System.exit(-1);
}
if( auth == null ){
log.warn("No authentication database specified, using password based auth with user \"admin\", password \"secret\"!");
Properties users = new Properties();
users.put("admin","secret");
auth = new SimplePasswordAuthenticator(users, new Properties() );
}
skip = 1;
AuditEventReader r = null;
int format = AuditFormat.guessFormat( auditFile );
if( format == AuditFormat.APACHE_ACCESS_LOG )
r = new AccessLogAuditReader( auditFile, skip > 0 );
if( format == AuditFormat.MOD_SECURITY_1_X_SERIAL_LOG )
r = new ModSecurityAuditReader( auditFile, skip > 0 );
if( format ==AuditFormat.MOD_SECURITY_2_X_SERIAL_LOG )
r = new ModSecurity2AuditReader( auditFile, skip > 0 );
if( format == AuditFormat.MOD_SECURITY_2_X_CONCURRENT_LOG ){
File dataDir = new File( auditFile.getParent() );
r = new ConcurrentAuditReader( auditFile, dataDir );
}
if( r == null ){
log.warn("Could not create reader for the audit-log file on "+auditFile.getAbsolutePath() );
System.exit(-1);
}
NetworkEventServer server = null;
try {
InputStream kurl = AuditServer.class.getResourceAsStream("/org/jwall/web/audit/net/keystore");
server = NetworkEventServer.createSSLEventServer( kurl, port, auth );
} catch (Exception e2) {
e2.printStackTrace();
System.exit(-1);
}
server.start();
AuditEventDispatcher d = new AuditEventDispatcher( r );
d.addAuditEventListener( server );
d.start();
//daemonize();
} catch (Exception e) {
e.printStackTrace();
}
}
public static void daemonize() throws Exception {
System.in.close();
System.err.close();
System.out.close();
}
public static void printUsage(){
try {
BufferedReader r = new BufferedReader(new InputStreamReader(AuditServer.class.getResourceAsStream("/org/jwall/server-usage.txt")));
String line = null;
do {
line = r.readLine();
if(line != null)
System.out.println(line);
} while(line != null);
r.close();
} catch (Exception e) {
e.printStackTrace();
}
}
public static void log( String msg ){
log.info( "[" + LOG_DATE.format( new Date() ) + "] org.jwall.AuditServer: " + msg );
}
}