org.jwall.apache.modsecurity.MSCollection Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of apache-config Show documentation
Show all versions of apache-config Show documentation
A Java library for reading Apache httpd configuration files
The newest version!
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
* Copyright (C) 2010-2014 Christian Bockermann
*
* This file is part of the jwall.org apache-config library. The apache-config library is
* a parsing library to handle Apache HTTPD configuration files.
*
* More information and documentation for the jwall-tools can be found at
*
* http://www.jwall.org/apache-config
*
* This program 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.
*
* This program 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.apache.modsecurity;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.logging.Logger;
/**
*
* This class implements a simple ModSecurity collection. The collection is backed
* by a HashMap for mapping keys to values. Each collection is associated with another
* name, i.e. this kind of implements an element of a hash of hashes.
*
*
* Almost everything of this class is set by the input map, i.e. it does contain user
* values as well as internal data (e.g. __key
), which is extracted separately
* for speedup (parsed only once).
*
*
* @author Christian Bockermann <[email protected]>
*
*/
public class MSCollection
implements Map
{
public final static String EXPIRE_PREFIX = "__expire_";
public final static String EXPIRE_KEY = "__expire_KEY";
public final static String COLLECTION_KEY = "KEY";
public final static String CREATION_TIME_KEY = "CREATE_TIME";
public final static String LAST_UPDATE_TIME_KEY = "LAST_UPDATE_TIME";
public final static String UPDATE_COUNTER_KEY = "UPDATE_COUNTER";
private final static String[] INTERNAL_KEYS = {
EXPIRE_KEY, COLLECTION_KEY, CREATION_TIME_KEY, UPDATE_COUNTER_KEY, LAST_UPDATE_TIME_KEY
};
static Logger log = Logger.getLogger( "MSCollection" );
static boolean verbose = System.getProperty( "verbose" ) != null;
/* The name of this collection, e.g. "ip", "resource", "session" */
String name;
/* This is the key of this collection, used to distinguish between several "ip" collections */
String key;
/* The map of values, i.e. the user-accessible stuff goes here */
Map valueMap;
/* The time of expiry of this collection */
Long expires = 0L;
/* The time this collection has been created */
Long created = 0L;
/* The time this collection has last been updated */
Long lastUpdate = 0L;
/**
* This is a protected constructor. The usual way of instantiating an MSCollection
* object is by the use of the static unpack
method.
*
* @param data The map of key-value pairs.
*/
protected MSCollection( Map data ){
this.valueMap = data;
try {
String sp = valueMap.get( EXPIRE_KEY );
if( sp != null )
expires = 1000 * Long.parseLong( sp.trim() );
sp = valueMap.get( CREATION_TIME_KEY );
if( sp != null )
created = 1000 * Long.parseLong( sp.trim() );
sp = valueMap.get( LAST_UPDATE_TIME_KEY );
if( sp != null )
lastUpdate = 1000 * Long.parseLong( sp.trim() );
} catch (Exception e) {
e.printStackTrace();
}
key = valueMap.get( "KEY" );
log.finest( "Collection has key \"" + key + "\"" );
}
/**
* This pretty much follows the unpack(..)
function of ModSecurity as can be
* found in persist_dbm.c
.
*
* @param data The data of a collection.
* @return A map containing all (key,value) pairs of the collection data.
*/
public static MSCollection unpack( byte[] data ){
Map map = new HashMap();
int offset = 3;
while( offset + 1 < data.length ){
int len = ( data[offset] << 8 ) + data[ offset + 1 ];
offset += 2;
if( len == 0 || offset >= data.length )
break;
String key = fromByteArray( data, offset, len );
offset += len;
len = ( data[offset] << 8 ) + data[ offset + 1 ];
offset += 2;
String value = fromByteArray( data, offset, len );
offset += len;
map.put( key.trim(), value );
}
return new MSCollection( map );
}
/*
* This method creates a string object from the given set of bytes, starting
* with character at index from
and ending after len
* bytes.
*
* @param data The data from which to create a string.
* @param from The position at which the string should start within the byte array.
* @param len The length of the string to be created.
* @return A new string, containing all characters from the byte array starting
* a from
ending at from + len
.
*/
private static String fromByteArray( byte[] data, int from, int len ){
StringBuffer s = new StringBuffer();
int end = from + len;
for( int i = from; i <= end && i < data.length; i++ )
s.append( (char) data[i] );
return s.toString();
}
/**
* Returns the key under which this collection is accessed from within
* the ModSecurity module.
*
* @return The key for this collection.
*/
public String getKey(){
return key;
}
/**
* This method returns the time (milliseconds) at which this collection
* will expire.
*
* @return The time stamp at which this collection expires.
*/
public Long expiresAt(){
return this.expires;
}
/**
* Returns true
, if this collection is already expired. This
* is just a convenience method which checks whether expire-time is beyond
* the current time.
*
* @return true
, if the collection is expired at the time
* this method is called.
*/
public boolean isExpired(){
return System.currentTimeMillis() >= expires;
}
//
//
// What follows here is simply the delegation of all Map interface method to
// the valueMap attribute.
//
//
public void clear()
{
valueMap.clear();
}
public boolean containsKey(Object key)
{
return valueMap.containsKey( key );
}
public boolean containsValue(Object value)
{
return valueMap.containsValue( value );
}
public Set> entrySet()
{
return valueMap.entrySet();
}
public String get(Object key)
{
return valueMap.get( key );
}
public boolean isEmpty()
{
return valueMap.isEmpty();
}
public Set keySet()
{
return valueMap.keySet();
}
public String put(String key, String value)
{
return valueMap.put( key.trim(), value );
}
public void putAll(Map extends String, ? extends String> t)
{
valueMap.putAll( t );
}
public String remove(Object key)
{
return valueMap.remove( key );
}
public int size()
{
return valueMap.size();
}
public Collection values()
{
return valueMap.values();
}
public String debug(){
StringBuffer s = new StringBuffer();
for( String k : keySet() ){
s.append(" ");
s.append( name );
s.append("[" + key + "].");
s.append( k + " = " + get( k ) );
s.append( "\n" );
}
return s.toString();
}
public String info(){
TimeFormat fmt = new TimeFormat();
StringBuffer s = new StringBuffer();
for( String k : keySet() ){
if( verbose || ! isInternalKey( k ) ) {
s.append(" ");
s.append( name );
s.append("[" + key + "].");
s.append( k + " = " + get( k ) );
String exp = get( EXPIRE_PREFIX + k );
if( exp != null ){
Long expire = (1000 * Long.parseLong( exp.trim() ) ) - System.currentTimeMillis();
if( expire < 0 ) {
if( System.getProperty("show.expired") != null )
s.append( " (expired " + fmt.format( - expire ) + " ago)" );
} else
s.append( " (expires in " + fmt.format( expire ) + ") ");
String lastUpdateStr = get( LAST_UPDATE_TIME_KEY );
Long lastUpdate = 1000 * Long.parseLong( lastUpdateStr.trim() ) - System.currentTimeMillis();
s.append( " last update was " + fmt.format( - lastUpdate ) + " ago " );
}
s.append( "\n" );
}
}
return s.toString();
}
private boolean isInternalKey( String str ){
String s = str.trim();
for( String internal : INTERNAL_KEYS )
if( s.equals( internal ) )
return true;
if( s.startsWith( EXPIRE_PREFIX ) )
return true;
if( s.startsWith( "__" ) )
return true;
return false;
}
public String toString(){
return toString( false );
}
public String toString( boolean verbose ){
StringBuffer s = new StringBuffer();
TimeFormat fmt = new TimeFormat();
s.append( " " );
s.append( "Created at " + new Date( this.created ) + "\n" );
if( verbose )
s.append( debug() );
else
s.append( info() );
long now = System.currentTimeMillis();
if( isExpired() ){
long ago = now - expiresAt();
s.append( "This collection expired " + fmt.format( ago ) + " seconds ago.\n");
} else
s.append( "This collection expires in " + fmt.format( expiresAt() - now ) + "\n") ;
return s.toString();
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy