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

org.jwall.apache.modsecurity.MSCollection Maven / Gradle / Ivy

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 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