package oculusPrime; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.File; import java.io.FileReader; import java.io.FileWriter; import java.io.RandomAccessFile; import java.net.Socket; import java.util.Date; import java.util.HashMap; import java.util.Map; import java.util.Vector; import java.util.Timer; import java.util.TimerTask; import oculusPrime.State.values; public class BanList { public static final String banfile = Settings.redhome+Util.sep+"conf"+Util.sep+"banlist.txt"; public static final String banlog = Settings.redhome+Util.sep + "log" + Util.sep + "banlist.log"; public static final long BAN_TIME_OUT = Util.FIVE_MINUTES; public static final int BAN_ATTEMPTS = 10; public static final int MAX_ATTEMPTS = 12; public static final int MAX_HISTORY = 50; private HashMap<String, Integer> attempts = new HashMap<String, Integer>(); private HashMap<String, Long> blocked = new HashMap<String, Long>(); private Vector<String> history = new Vector<String>(); private Vector<String> banned = new Vector<String>(); private Vector<String> known = new Vector<String>(); private State state = State.getReference(); private RandomAccessFile logfile = null; private Timer timer = new Timer(); static BanList singleton = new BanList(); public static BanList getRefrence(){ return singleton; } private BanList() { try { File ban = new File(banfile); if(ban.exists()) { String line = null; BufferedReader br = new BufferedReader(new FileReader(ban)); while((line = br.readLine()) != null) { String addr = line.trim(); if(Util.validIP(addr)) banned.add(addr); } br.close(); } } catch (Exception e) { Util.log(e.getLocalizedMessage(), this); } // File log = new File(banlog); // if (log.exists()) { // if (log.length() > ROLL_OVER) { // Util.log("BanList(): file too large, rolling over: " + log.getAbsolutePath(), this); // log.delete(); // } // } try { logfile = new RandomAccessFile(banlog, "rw"); } catch (Exception e) { Util.debug("BanList(): " + e.getMessage()); } timer.scheduleAtFixedRate(new ClearTimer(), 0, Util.ONE_MINUTE); } public String tail(int lines){ int i = 0; StringBuffer str = new StringBuffer(); if(history.size() > lines) i = history.size() - lines; for(; i < history.size() ; i++) str.append(history.get(i) + "\n<br />"); return str.toString(); } private void appendLog(final String str){ if(history.size() > MAX_HISTORY) history.remove(0); history.add(Util.getTime() + ", " + str); if(logfile==null) return; try { logfile.seek(logfile.length()); logfile.writeBytes(new Date().toString() + ", " + str + "\r\n"); } catch (Exception e) { Util.debug("BanList.appendLog(): " + e.getMessage() + " " + str); } } public synchronized void removeblockedFile(final String address) { appendLog("remove from file: " + address); if(banned.contains(address)) banned.remove(address); clearAddress(address); writeFile(); } public synchronized void addBlockedFile(final String ip){ if(Util.validIP(ip)){ appendLog("adding to file: " + ip); banned.add(ip); writeFile(); } } private void writeFile(){ try { BufferedWriter bw = new BufferedWriter(new FileWriter(new File(banfile))); for(int i = 0 ; i < banned.size() ; i++) if(Util.validIP(banned.get(i))) bw.append(banned.get(i) + " \n\r"); bw.close(); } catch (Exception e) { Util.log("writeFile(): ", e, this); } } public synchronized boolean isBanned(Socket socket) { return isBanned(socket.getInetAddress().toString().substring(1)); } public synchronized boolean isBanned(final String address) { if(address.equals("127.0.0.1")) return false; if(!Settings.getReference().getBoolean(ManualSettings.checkaddresses)) return false; if(banned.contains(address)) { appendLog("banned address: " + address); if(known.contains(address)) known.remove(address); return true; } if(blocked.containsKey(address)) { appendLog("blocked address: " + address); if(attempts.containsKey(address)) attempts.put(address, attempts.get(address)+1); if(attempts.get(address) >= MAX_ATTEMPTS){ appendLog("now banned: " + address); if(known.contains(address)) known.remove(address); addBlockedFile(address); } return true; } return false; } public synchronized boolean knownAddress(final String address) { if(!Settings.getReference().getBoolean(ManualSettings.checkaddresses)) return true; if( ! Util.validIP(address)) return false; if(address.equals("0.0.0.0")) return true; if(address.equals("127.0.0.1")) return true; if(address.startsWith("10.42")) return true; if (known.contains(address)) return true; if (state.exists(values.localaddress)) { String firsttwonums = state.get(values.localaddress).replaceFirst("\\.\\d+\\.\\d+$", ""); if (address.replaceFirst("\\.\\d+\\.\\d+$", "").equals(firsttwonums)) { if (!known.contains(address)) { appendLog("added lan ip: " + address); known.add(address); } return true; } } if(isBanned(address)) return false; return known.contains(address); } public synchronized void clearAddress(String address) { if(address == null) return; if(address.equals("null")) return; if( ! Util.validIP(address)){ appendLog(address + " is not a valid address?"); return; } if(attempts.containsKey(address)) attempts.remove(address); if(blocked.containsKey(address)) blocked.remove(address); if( ! known.contains(address)) known.add(address); } public synchronized void loginFailed(final String remoteAddress, final String user) { if(remoteAddress.equals("127.0.0.1")) return; if(banned.contains(remoteAddress)) Util.log("DANGEROUS..failed sanity check: " + user, this); if(attempts.containsKey(remoteAddress)) attempts.put(remoteAddress, attempts.get(remoteAddress)+1); else attempts.put(remoteAddress, 1); if(known.contains(remoteAddress)) known.remove(remoteAddress); appendLog("login failed: " + remoteAddress + " user: " + user + " attempts: " + attempts.get(remoteAddress)); if(attempts.get(remoteAddress) >= BAN_ATTEMPTS){ appendLog("now blocked: " + remoteAddress + " user: " + user); blocked.put(remoteAddress, System.currentTimeMillis()); } } private class ClearTimer extends TimerTask { @Override public void run() { // if(state.exists(values.gateway)){ // if( ! known.contains(state.get(values.gateway))) // known.add(state.get(values.gateway)); // } if(state.exists(values.localaddress)){ if( ! known.contains(state.get(values.localaddress))) known.add(state.get(values.localaddress)); } // if(state.exists(values.ethernetaddress)){ // if( ! known.contains(state.get(values.ethernetaddress))) // known.add(state.get(values.ethernetaddress)); // } if(blocked.isEmpty()) return; try { for (Map.Entry<String, Long> entry : blocked.entrySet()) { if((entry.getValue()+BAN_TIME_OUT) < System.currentTimeMillis()){ appendLog("removed from blocked list: " + entry.getKey()); clearAddress(entry.getKey()); } } } catch (Exception e) { Util.log("ClearTimer(): ", e, this); } } } @Override public String toString(){ // if(override) return " override: " + banned.toString(); return " banned: " + banned.toString() + " known:" + known.toString(); } }