001    /**
002     * Jetrix TetriNET Server
003     * Copyright (C) 2001-2003  Emmanuel Bourg
004     *
005     * This program is free software; you can redistribute it and/or
006     * modify it under the terms of the GNU General Public License
007     * as published by the Free Software Foundation; either version 2
008     * of the License, or (at your option) any later version.
009     *
010     * This program is distributed in the hope that it will be useful,
011     * but WITHOUT ANY WARRANTY; without even the implied warranty of
012     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
013     * GNU General Public License for more details.
014     *
015     * You should have received a copy of the GNU General Public License
016     * along with this program; if not, write to the Free Software
017     * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
018     */
019    
020    package net.jetrix;
021    
022    import java.util.*;
023    import java.util.regex.*;
024    import java.net.*;
025    
026    /**
027     * List of hosts banned from the server.
028     *
029     * @author Emmanuel Bourg
030     * @version $Revision: 794 $, $Date: 2009-02-17 20:08:39 +0100 (Tue, 17 Feb 2009) $
031     */
032    public class Banlist
033    {
034        private static Banlist instance = new Banlist();
035        private Map<String, Entry> banlist;
036    
037        private Banlist()
038        {
039            banlist = new HashMap<String, Entry>();
040        }
041    
042        public static Banlist getInstance()
043        {
044            return instance;
045        }
046    
047        /**
048         * Ban the specified host forever.
049         */
050        public void ban(String host)
051        {
052            ban(host, null);
053        }
054    
055        /**
056         * Ban the specified host till the expiration date.
057         */
058        public void ban(String host, Date expiration)
059        {
060            banlist.put(host, new Entry(host, expiration));
061        }
062    
063        /**
064         * Unban the specified host.
065         */
066        public void unban(String host)
067        {
068            banlist.remove(host);
069        }
070    
071        /**
072         * Check if the specified host is currently banned.
073         */
074        public boolean isBanned(String host)
075        {
076            boolean banned = false;
077    
078            Date now = new Date();
079    
080            Iterator<Entry> it = banlist.values().iterator();
081            while (it.hasNext() && !banned)
082            {
083                Entry entry = it.next();
084                banned = entry.matches(host);
085    
086                // test the expiration date
087                if (banned && entry.expiration != null)
088                {
089                    if (now.after(entry.expiration))
090                    {
091                        // the ban has expired
092                        banned = false;
093    
094                        // remove the entry from the banlist
095                        it.remove();
096                    }
097                }
098            }
099    
100            return banned;
101        }
102    
103        public boolean isBanned(InetAddress address)
104        {
105            return isBanned(address.getHostAddress()) || isBanned(address.getHostName());
106        }
107    
108        public Iterator<Entry> getBanlist()
109        {
110            return banlist.values().iterator();
111        }
112    
113        /**
114         * Remove all entries in the banlist.
115         */
116        public void clear()
117        {
118            banlist.clear();
119        }
120    
121        /**
122         * A ban list entry.
123         */
124        public class Entry
125        {
126            public String pattern;
127            public Date expiration;
128            private Pattern regexp;
129    
130            public Entry(String pattern, Date expiration)
131            {
132                this.pattern = pattern;
133                this.expiration = expiration;
134            }
135    
136            public boolean matches(String value)
137            {
138                if (regexp == null)
139                {
140                    // replace . by \., * by .* and ? by .
141                    String s = pattern.replaceAll("\\.", "\\\\.").replaceAll("\\*", "(.*)").replaceAll("\\?", ".");
142                    regexp = Pattern.compile(s);
143                }
144    
145                return regexp.matcher(value).matches();
146            }
147        }
148    
149    }