added IP ban facility - IP addresses can now be blocked from logging into

Venice, either individually or in blocks
This commit is contained in:
Eric J. Bowersox
2004-05-31 03:38:41 +00:00
parent 55db78c0e9
commit 609d216148
19 changed files with 959 additions and 32 deletions

View File

@@ -0,0 +1,104 @@
/*
* The contents of this file are subject to the Mozilla Public License Version 1.1
* (the "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at <http://www.mozilla.org/MPL/>.
*
* Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
* WARRANTY OF ANY KIND, either express or implied. See the License for the specific
* language governing rights and limitations under the License.
*
* The Original Code is the Venice Web Communities System.
*
* The Initial Developer of the Original Code is Eric J. Bowersox <erbo@ricochet.com>,
* for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
* Copyright (C) 2004 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
*
* Contributor(s):
*/
package com.silverwrist.util;
import org.apache.regexp.*;
public class IPv4Util
{
/*--------------------------------------------------------------------------------
* Static data members
*--------------------------------------------------------------------------------
*/
public static final long MAX_ADDRESS = 0xFFFFFFFFL;
private static final REProgram IPV4_PATTERN =
new RECompiler().compile("^\\s*(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\s*$");
/*--------------------------------------------------------------------------------
* Constructors
*--------------------------------------------------------------------------------
*/
public IPv4Util()
{ // only present for bean-like environments - do not construct this object directly
} // end constructor
/*--------------------------------------------------------------------------------
* External static operations
*--------------------------------------------------------------------------------
*/
public static final boolean isValid(String ip_addr)
{
if (ip_addr==null)
return false;
RE matcher = new RE(IPV4_PATTERN);
if (!matcher.match(ip_addr))
return false;
for (int i=1; i<=4; i++)
{ // parse long integers, assemble into return value
int val = Integer.parseInt(matcher.getParen(i));
if ((val<0) || (val>255))
return false;
} // end for
return true;
} // end isValid
public static final long stringToLongAddress(String ip_addr) throws IllegalArgumentException
{
RE matcher = new RE(IPV4_PATTERN);
if (!(matcher.match(ip_addr)))
throw new IllegalArgumentException("invalid IP address: " + ip_addr);
long rc = 0;
for (int i=1; i<=4; i++)
{ // parse long integers, assemble into return value
long val = Long.parseLong(matcher.getParen(i));
if ((val<0) || (val>255))
throw new IllegalArgumentException("invalid IP address: " + ip_addr);
rc = (rc << 8) | val;
} // end for
return rc;
} // end stringToLongAddress
public static final String longToStringAddress(long addr) throws IllegalArgumentException
{
if ((addr<0) || (addr>MAX_ADDRESS))
throw new IllegalArgumentException("invalid IP address: " + addr);
StringBuffer rc = new StringBuffer(16);
for (int i=0; i<4; i++)
{ // build string representation from the right up
rc.insert(0,addr & 0xFFL);
rc.insert(0,'.');
addr >>= 8;
} // end for
rc.delete(0,1);
return rc.toString();
} // end longToStringAddress
} // end class IPv4Util

View File

@@ -9,9 +9,9 @@
*
* The Original Code is the Venice Web Communities System.
*
* The Initial Developer of the Original Code is Eric J. Bowersox <erbo@silcom.com>,
* The Initial Developer of the Original Code is Eric J. Bowersox <erbo@ricochet.com>,
* for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
* Copyright (C) 2001-02 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
* Copyright (C) 2001-2004 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
*
* Contributor(s):
*/
@@ -49,4 +49,15 @@ public interface AdminOperations
String description, boolean auto_join)
throws DataException, AccessError;
public abstract List getIPBanInfo() throws DataException;
public abstract IPBanInfo getIPBanInfo(int id) throws DataException;
public abstract void enableIPBan(int id, boolean enab) throws DataException;
public abstract void removeIPBan(int id) throws DataException;
public abstract void addIPBan(String address, String mask, java.util.Date expires, String message)
throws DataException;
} // end interface AdminOperations

View File

@@ -0,0 +1,38 @@
/*
* The contents of this file are subject to the Mozilla Public License Version 1.1
* (the "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at <http://www.mozilla.org/MPL/>.
*
* Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
* WARRANTY OF ANY KIND, either express or implied. See the License for the specific
* language governing rights and limitations under the License.
*
* The Original Code is the Venice Web Communities System.
*
* The Initial Developer of the Original Code is Eric J. Bowersox <erbo@ricochet.com>,
* for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
* Copyright (C) 2004 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
*
* Contributor(s):
*/
package com.silverwrist.venice.core;
public interface IPBanInfo
{
public abstract int getID();
public abstract String getAddress();
public abstract String getMask();
public abstract boolean isEnabled();
public abstract java.util.Date getExpire();
public abstract String getMessage();
public abstract String getBlockedBy();
public abstract java.util.Date getBlockedOn();
} // end interface IPBanInfo

View File

@@ -9,9 +9,9 @@
*
* The Original Code is the Venice Web Communities System.
*
* The Initial Developer of the Original Code is Eric J. Bowersox <erbo@silcom.com>,
* The Initial Developer of the Original Code is Eric J. Bowersox <erbo@ricochet.com>,
* for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
* Copyright (C) 2001-02 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
* Copyright (C) 2001-2004 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
*
* Contributor(s):
*/
@@ -91,4 +91,6 @@ public interface VeniceEngine extends SearchMode, ServiceGroup
public abstract boolean useCategories();
public abstract String testIPBan(String ip_address) throws DataException;
} // end interface VeniceEngine

View File

@@ -9,9 +9,9 @@
*
* The Original Code is the Venice Web Communities System.
*
* The Initial Developer of the Original Code is Eric J. Bowersox <erbo@silcom.com>,
* The Initial Developer of the Original Code is Eric J. Bowersox <erbo@ricochet.com>,
* for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
* Copyright (C) 2001-02 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
* Copyright (C) 2001-2004 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
*
* Contributor(s):
*/
@@ -20,6 +20,7 @@ package com.silverwrist.venice.core.impl;
import java.sql.*;
import java.util.*;
import org.apache.log4j.*;
import com.silverwrist.util.*;
import com.silverwrist.venice.core.*;
import com.silverwrist.venice.core.internals.*;
import com.silverwrist.venice.db.*;
@@ -30,6 +31,113 @@ import com.silverwrist.venice.svc.GlobalSite;
class AdminOperationsImpl implements AdminOperations
{
/*--------------------------------------------------------------------------------
* Internal class for IP ban listings
*--------------------------------------------------------------------------------
*/
private static class IPBanInfoImpl implements IPBanInfo
{
/*====================================================================
* Attributes
*====================================================================
*/
private int m_id;
private String m_address;
private String m_mask;
private boolean m_enabled;
private java.util.Date m_expires;
private String m_message;
private String m_blocked_by;
private java.util.Date m_blocked_on;
/*====================================================================
* Constructors
*====================================================================
*/
IPBanInfoImpl(ResultSet rs) throws SQLException
{
m_id = rs.getInt(1);
m_address = IPv4Util.longToStringAddress(rs.getLong(2));
m_mask = IPv4Util.longToStringAddress(rs.getLong(3));
m_enabled = (rs.getInt(4)!=0);
m_expires = SQLUtil.getFullDateTime(rs,5);
m_message = rs.getString(6);
m_blocked_by = rs.getString(7);
m_blocked_on = SQLUtil.getFullDateTime(rs,8);
} // end constructor
IPBanInfoImpl(int id, ResultSet rs) throws SQLException
{
m_id = id;
m_address = IPv4Util.longToStringAddress(rs.getLong(1));
m_mask = IPv4Util.longToStringAddress(rs.getLong(2));
m_enabled = (rs.getInt(3)!=0);
m_expires = SQLUtil.getFullDateTime(rs,4);
m_message = rs.getString(5);
m_blocked_by = rs.getString(6);
m_blocked_on = SQLUtil.getFullDateTime(rs,7);
} // end constructor
/*====================================================================
* Implementations from interface IPBanInfo
*====================================================================
*/
public final int getID()
{
return m_id;
} // end getID
public final String getAddress()
{
return m_address;
} // end getAddress
public final String getMask()
{
return m_mask;
} // end getMask
public final boolean isEnabled()
{
return m_enabled;
} // end isEnabled
public final java.util.Date getExpire()
{
return m_expires;
} // end getExpire
public final String getMessage()
{
return m_message;
} // end getMessage
public final String getBlockedBy()
{
return m_blocked_by;
} // end getBlockedBy
public final java.util.Date getBlockedOn()
{
return m_blocked_on;
} // end getBlockedOn
} // end class IPBanInfoImpl
/*--------------------------------------------------------------------------------
* Static data members
*--------------------------------------------------------------------------------
@@ -197,4 +305,183 @@ class AdminOperationsImpl implements AdminOperations
} // end createNewAccount
public List getIPBanInfo() throws DataException
{
ArrayList rc = null;
Connection conn = null;
Statement stmt = null;
ResultSet rs = null;
try
{ // retrieve a connection from the data pool and get the audit records
conn = globalsite.getConnection(null);
stmt = conn.createStatement();
rs = stmt.executeQuery("SELECT b.id, b.address, b.mask, b.enable, b.expire, b.message, u.username, b.block_on "
+ "FROM ipban b, users u WHERE u.uid = b.block_by ORDER BY b.block_on;");
while (rs.next())
{ // extract the listing of IP blocks
if (rc==null)
rc = new ArrayList();
rc.add(new IPBanInfoImpl(rs));
} // end while
} // end try
catch (SQLException e)
{ // database error - this is a DataException
logger.error("error loading IP ban info: " + e.getMessage(),e);
throw new DataException("unable to load IP ban info: " + e.getMessage(),e);
} // end catch
finally
{ // make sure the connection is released before we go
SQLUtil.shutdown(rs);
SQLUtil.shutdown(stmt);
SQLUtil.shutdown(conn);
} // end finally
if ((rc==null) || rc.isEmpty())
return Collections.EMPTY_LIST;
rc.trimToSize();
return Collections.unmodifiableList(rc);
} // end getIPBanInfo
public IPBanInfo getIPBanInfo(int id) throws DataException
{
Connection conn = null;
PreparedStatement stmt = null;
ResultSet rs = null;
try
{ // retrieve a connection from the data pool and get the audit records
conn = globalsite.getConnection(null);
stmt = conn.prepareStatement("SELECT b.address, b.mask, b.enable, b.expire, b.message, u.username, b.block_on "
+ "FROM ipban b, users u WHERE u.uid = b.block_by AND b.id = ?;");
stmt.setInt(1,id);
rs = stmt.executeQuery();
if (rs.next())
return new IPBanInfoImpl(id,rs);
} // end try
catch (SQLException e)
{ // database error - this is a DataException
logger.error("error loading IP ban info: " + e.getMessage(),e);
throw new DataException("unable to load IP ban info: " + e.getMessage(),e);
} // end catch
finally
{ // make sure the connection is released before we go
SQLUtil.shutdown(rs);
SQLUtil.shutdown(stmt);
SQLUtil.shutdown(conn);
} // end finally
return null;
} // end getIPBanInfo
public void enableIPBan(int id, boolean enab) throws DataException
{
Connection conn = null;
PreparedStatement stmt = null;
try
{ // retrieve a connection from the data pool and get the audit records
conn = globalsite.getConnection(null);
stmt = conn.prepareStatement("UPDATE ipban SET enable = ? WHERE id = ?;");
stmt.setInt(1,enab ? 1 : 0);
stmt.setInt(2,id);
stmt.executeUpdate();
} // end try
catch (SQLException e)
{ // database error - this is a DataException
logger.error("error setting IP ban info: " + e.getMessage(),e);
throw new DataException("unable to change IP ban info: " + e.getMessage(),e);
} // end catch
finally
{ // make sure the connection is released before we go
SQLUtil.shutdown(stmt);
SQLUtil.shutdown(conn);
} // end finally
} // end enableIPBan
public void removeIPBan(int id) throws DataException
{
Connection conn = null;
PreparedStatement stmt = null;
try
{ // retrieve a connection from the data pool and get the audit records
conn = globalsite.getConnection(null);
stmt = conn.prepareStatement("DELETE FROM ipban WHERE id = ?;");
stmt.setInt(1,id);
stmt.executeUpdate();
} // end try
catch (SQLException e)
{ // database error - this is a DataException
logger.error("error setting IP ban info: " + e.getMessage(),e);
throw new DataException("unable to change IP ban info: " + e.getMessage(),e);
} // end catch
finally
{ // make sure the connection is released before we go
SQLUtil.shutdown(stmt);
SQLUtil.shutdown(conn);
} // end finally
} // end removeIPBan
public void addIPBan(String address, String mask, java.util.Date expires, String message) throws DataException
{
Connection conn = null;
PreparedStatement stmt = null;
try
{ // retrieve a connection from the data pool and get the audit records
conn = globalsite.getConnection(null);
stmt = conn.prepareStatement("INSERT INTO ipban (address, mask, expire, message, block_by, block_on) "
+ "VALUES (?, ?, ?, ?, ?, ?);");
try
{ // set the two IP address fields
stmt.setLong(1,IPv4Util.stringToLongAddress(address));
stmt.setLong(2,IPv4Util.stringToLongAddress(mask));
} // end try
catch (IllegalArgumentException e)
{ // translate to DataException
throw new DataException(e);
} // end catch
SQLUtil.setFullDateTime(stmt,3,expires);
stmt.setString(4,message);
stmt.setInt(5,env.getUserID());
SQLUtil.setFullDateTime(stmt,6,new java.util.Date());
stmt.executeUpdate();
} // end try
catch (SQLException e)
{ // database error - this is a DataException
logger.error("error setting IP ban info: " + e.getMessage(),e);
throw new DataException("unable to change IP ban info: " + e.getMessage(),e);
} // end catch
finally
{ // make sure the connection is released before we go
SQLUtil.shutdown(stmt);
SQLUtil.shutdown(conn);
} // end finally
} // end addIPBan
} // end class AdminOperationsImpl

View File

@@ -9,9 +9,9 @@
*
* The Original Code is the Venice Web Communities System.
*
* The Initial Developer of the Original Code is Eric J. Bowersox <erbo@silcom.com>,
* The Initial Developer of the Original Code is Eric J. Bowersox <erbo@ricochet.com>,
* for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
* Copyright (C) 2001-02 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
* Copyright (C) 2001-2004 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
*
* Contributor(s):
*/
@@ -1336,6 +1336,56 @@ public class VeniceEngineImpl implements VeniceEngine, ServiceProvider, EngineBa
} // end useCategories
public String testIPBan(String ip_address) throws DataException
{
checkInitialized();
long addy = 0;
try
{ // convert the IP address parameter to a long integer
addy = IPv4Util.stringToLongAddress(ip_address);
} // end try
catch (IllegalArgumentException e)
{ // wrap the exception and return it
throw new DataException(e);
} // end catch
Connection conn = null;
PreparedStatement stmt = null;
ResultSet rs = null;
try
{ // Look for an IP ban that (a) matches this IP address (by mask), (b) has not yet expired (or does not
// expire), and (c) is enabled.
conn = globalsite.getConnection(null);
stmt = conn.prepareStatement("SELECT message FROM ipban WHERE (address & mask) = (? & mask) "
+ "AND (expire IS NULL OR expire >= ?) AND enable <> 0 ORDER BY mask DESC "
+ "LIMIT 1;");
stmt.setLong(1,addy);
stmt.setString(2,SQLUtil.encodeDate(new java.util.Date()));
rs = stmt.executeQuery();
if (rs.next()) // located an IP ban
return rs.getString(1);
} // end try
catch (SQLException e)
{ // bug out
throw new DataException("Error accessing IP ban database: " + e.getMessage(),e);
} // end catch
finally
{ // make sure the connection is released before we go
SQLUtil.shutdown(rs);
SQLUtil.shutdown(stmt);
SQLUtil.shutdown(conn);
} // end finally
return null; // no IP ban found
} // end testIPBan
/*--------------------------------------------------------------------------------
* Implementations from interface ServiceProvider
*--------------------------------------------------------------------------------

View File

@@ -228,6 +228,15 @@ public class SQLUtil
} // end encodeDate
public static final void setFullDateTime(PreparedStatement stmt, int index, java.util.Date date) throws SQLException
{
if (date==null)
stmt.setNull(index,java.sql.Types.TIMESTAMP);
else
stmt.setString(index,encodeDate(date));
} // end setFullDateTime
/**
* Returns the value of a DATETIME column in the current row of an SQL result set, formatted as a date.
*

View File

@@ -9,9 +9,9 @@
*
* The Original Code is the Venice Web Communities System.
*
* The Initial Developer of the Original Code is Eric J. Bowersox <erbo@silcom.com>,
* The Initial Developer of the Original Code is Eric J. Bowersox <erbo@ricochet.com>,
* for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
* Copyright (C) 2001 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
* Copyright (C) 2001-2004 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
*
* Contributor(s):
*/
@@ -38,9 +38,9 @@ public class DialogElementLoader
private static final Class[] init_classes = {
CategoryHeader.class, CheckBoxField.class, CommunityLogoField.class, CountryListField.class,
EMailAddressField.class, HiddenField.class, ImageButton.class, IntegerField.class,
LanguageListField.class, LocaleListField.class, PasswordField.class, RoleListField.class,
StaticPickListField.class, TextField.class, TimeZoneListField.class, UserPhotoField.class,
VeniceIDField.class
IPAddressField.class, LanguageListField.class, LocaleListField.class, PasswordField.class,
RoleListField.class, StaticPickListField.class, TextField.class, TimeZoneListField.class,
UserPhotoField.class, VeniceIDField.class
};
/*--------------------------------------------------------------------------------

View File

@@ -0,0 +1,83 @@
/*
* The contents of this file are subject to the Mozilla Public License Version 1.1
* (the "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at <http://www.mozilla.org/MPL/>.
*
* Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
* WARRANTY OF ANY KIND, either express or implied. See the License for the specific
* language governing rights and limitations under the License.
*
* The Original Code is the Venice Web Communities System.
*
* The Initial Developer of the Original Code is Eric J. Bowersox <erbo@ricochet.com>,
* for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
* Copyright (C) 2004 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
*
* Contributor(s):
*/
package com.silverwrist.venice.ui.dlg;
import java.io.IOException;
import org.w3c.dom.*;
import com.silverwrist.util.*;
import com.silverwrist.venice.except.*;
import com.silverwrist.venice.ui.*;
import com.silverwrist.venice.util.XMLLoader;
public class IPAddressField extends TextField
{
/*--------------------------------------------------------------------------------
* Static data members
*--------------------------------------------------------------------------------
*/
public static final String TAGNAME = "ip-address";
/*--------------------------------------------------------------------------------
* Constructors
*--------------------------------------------------------------------------------
*/
public IPAddressField(String name, String caption, String caption2)
{
super(name,caption,caption2,true,15);
} // end constructor
public IPAddressField(Element elt) throws ConfigException
{
super(elt,15);
} // end constructor
protected IPAddressField(IPAddressField other)
{
super(other);
} // end constructor
/*--------------------------------------------------------------------------------
* Overrides from class TextField
*--------------------------------------------------------------------------------
*/
protected void validateContents(String value) throws ValidationException
{
super.validateContents(value);
if (!(IPv4Util.isValid(value)))
throw new ValidationException("Invalid IP address in the '" + getCaption() + "' field.");
} // end validateContents
/*--------------------------------------------------------------------------------
* Implementations from interface DialogField
*--------------------------------------------------------------------------------
*/
public DialogField duplicate()
{
return new IPAddressField(this);
} // end duplicate
} // end class IPAddressField