Package org.jwall.rbl.net

Source Code of org.jwall.rbl.net.AdminHandler

/*******************************************************************************
* Copyright (C) 2010 Christian Bockermann <chris@jwall.org>
* This file is part of the jwall-rbld program. jwall-rbld is an implementation
* of a simple DNS server for running a local, customized real time block-list.
* More information and documentation for the jwall-rbld can be found at
*
*                    http://www.jwall.org/jwall-rbld
*
* 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 <http://www.gnu.org/licenses/>.
******************************************************************************/
package org.jwall.rbl.net;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.List;

import org.jwall.rbl.RblServer;
import org.jwall.rbl.data.RBListEntry;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
* <p>
* This thread is a simple text-based tcp client, which accepts connections from
* localhost only and provides a very small set of simple commands to manage the
* RB-list of this server.
* </p>
*
* @author Christian Bockermann &lt;chris@jwall.org&gt;
*
*/
public class AdminHandler extends Thread {

  static Logger log = LoggerFactory.getLogger(AdminHandler.class);

  /* The rbl-server this handler manages */
  RblServer server;

  /* The server socket */
  ServerSocket socket;

  /* A flag indicating whether the handler is running or not */
  boolean running = true;

  /**
   * Creates a new AdminHandler for the specified server, listening on the
   * given address and port.
   *
   * @param server
   * @param addr
   * @param port
   * @throws Exception
   */
  public AdminHandler(RblServer server, String addr, int port)
      throws Exception {
    this.socket = new ServerSocket(port);
    this.server = server;
    this.setDaemon(true);
  }

  public void run() {
    while (running) {
      try {
        Socket client = socket.accept();
        String remote = client.getInetAddress().getHostAddress();
        if (!(remote.startsWith("127.0.0") || remote
            .equals("0:0:0:0:0:0:0:1")) || remote.equals("::1")) {
          log.info("Client connect from {} rejected. Allowing localhost connections only!",
                  client.getInetAddress().getHostAddress());
          client.close();
        } else {
          ClientHandler handler = new ClientHandler(client, server);
          handler.start();
        }
      } catch (Exception e) {
        e.printStackTrace();
      }
    }
  }

  public void shutdown() {
    running = false;
    this.interrupt();
  }

  /**
   * This is a per-connection thread for handling a connection.
   *
   * @author Christian Bockermann &lt;chris@jwall.org&gt;
   *
   */
  public class ClientHandler extends Thread {

    RblServer server;
    PrintStream out;
    BufferedReader reader;
    Socket socket;
    boolean running = true;

    public ClientHandler(Socket socket, RblServer server) {
      this.setDaemon(true);
      this.socket = socket;
      this.server = server;
    }

    public void run() {

      try {
        reader = new BufferedReader(new InputStreamReader(
            socket.getInputStream()));
        out = new PrintStream(socket.getOutputStream());
        out.println("\n   jwall.org RBL Server " + RblServer.VERSION);
        out.print("   ---------------------");
        for (int i = 0; i < RblServer.VERSION.length(); i++)
          out.print("-");
        out.println("\n");
        out.println("   Welcome to the jwall-rbl server, Version "
            + RblServer.VERSION);
        out.println("   This interface allows you to manage the block-list of this server.");
        out.println("   Type 'help' to get an overview of the available commands!");

        while (running && socket.isConnected()) {
          out.print("\n> ");
          String line = reader.readLine();
          if (line != null) {
            eval(line.trim());
          }
        }

        out.println("# Bye!");
        out.flush();
        out.close();
        socket.close();
      } catch (Exception e) {
        e.printStackTrace();
      }
    }

    public void eval(String command) {
      String[] args = command.split("\\s+");
      if (args.length == 0)
        return;

      if ("help".startsWith(args[0])) {
        doHelp();
        return;
      }

      if ("list".startsWith(args[0])) {
        doList(args);
        return;
      }

      if ("search".startsWith(args[0])) {
        doSearch(args);
        return;
      }

      if ("block".startsWith(args[0])) {
        doBlock(args);
        return;
      }

      if ("unblock".startsWith(args[0])) {
        doUnblock(args);
        return;
      }

      if ("quit".startsWith(args[0]) || "exit".startsWith(args[0])) {
        running = false;
        return;
      }

      if ("shutdown".startsWith(args[0])) {
        doShutdown(args);
      }

      out.println("Unknown command '" + args[0] + "'!");
    }

    public void doHelp() {
      out.println("   This is a very simple interface for adding/removing entries");
      out.println("   from the server's block list.");
      out.println("   Any changes to the list will immediately affect the server's");
      out.println("   response, thus it may be used for instant blocking.\n");
      out.println("   The following commands are availble:\n");
      out.println("      'search'   - simply lists all active entries, matching a given");
      out.println("                   expression. '*' and '?' can be used as wildcards\n");
      out.println("      'list'     - Lists all entries currently active.\n");
      out.println("      'block'    - Creates a new list-entry. By default an entry will");
      out.println("                   be blocked for 60 seconds. You may additionally specify");
      out.println("                   any other number of seconds before this entry expires.\n");
      out.println("      'unblock'  - Removes an entry from the list.");
    }

    public void doList(String[] args) {
      doSearch(new String[] { "search", "*" });
      return;
    }

    public void doBlock(String[] args) {

      if (args.length == 1) {
        out.println("");
        out.println("   You need to specify an additional IP address to block!");
        out.println("   Example:");
        out.println("                  block 172.16.0.1\n");
        out.println("   You may also specify the number of seconds until the block ");
        out.println("   expires, e.g.");
        out.println("                  block 172.16.0.1 180\n");
        return;
      }

      try {
        String[] tok = args[1].split("\\.");
        StringBuffer key = new StringBuffer();
        for (int i = tok.length - 1; i >= 0; i--) {
          key.append(tok[i]);
          if (i > 0)
            key.append(".");
        }

        if (!server.getDomain().startsWith("."))
          key.append(".");
        key.append(server.getDomain());

        RBListEntry entry = new RBListEntry(null, key.toString());
        entry.setName(args[1]);
        entry.setCreated(System.currentTimeMillis());
        try {
          if (args.length > 2)
            entry.setLifetime(new Integer(args[2]));
        } catch (Exception e) {
          entry.setLifetime(60);
        }

        entry.setComment("");
        server.getBlockList().add(entry);
        out.println("# Address '" + entry.getName()
            + "' added to block-list.");
      } catch (Exception e) {
        out.println("# Failed to create address '" + args[1] + "' - "
            + e.getMessage());
        e.printStackTrace();
        return;
      }
    }

    public void doUnblock(String[] args) {
      try {
        String[] tok = args[1].split("\\.");
        StringBuffer key = new StringBuffer();
        for (int i = tok.length - 1; i >= 0; i--) {
          key.append(tok[i]);
          if (i > 0)
            key.append(".");
        }

        if (!server.getDomain().startsWith("."))
          key.append(".");
        key.append(server.getDomain());

        server.getBlockList().remove(key.toString());
        out.println("# Removed '" + key.toString()
            + "' from block list.");
      } catch (Exception e) {
        out.println("Failed to remove address from block list: "
            + e.getMessage());
        e.printStackTrace();
      }
    }

    public void doSearch(String[] args) {
      if (args.length == 1) {
        out.println("\n   The 'search' command needs an additional query string!");
        return;
      }

      try {
        List<RBListEntry> results = server.getBlockList().search(
            args[1]);
        for (RBListEntry entry : results) {
          long expired = (entry.getExpiresAt() - System
              .currentTimeMillis()) / 1000;
          String expires = "  expires in " + expired + " seconds.";
          if (expired < 0) {
            expires = "  expired " + Math.abs(expired)
                + " seconds ago.";
            if (Math.abs(expired) > 120) {
              server.getBlockList().remove(entry.getName());
              continue;
            }
          }
          out.println("  " + entry.getName() + "   " + expires);
        }
      } catch (Exception e) {
        e.printStackTrace();
      }
    }

    public void doShutdown(String args[]) {
      out.print("Do you really want to shut down the RBL daemon?  (Y/N)  ");
      try {
        String line = reader.readLine();
        if (line != null && line.trim().matches("(Y|y)")) {
          out.println();
          out.println("Sending 'shutdown' command to server...");
          server.shutdown();
          running = false;
        } else {
          out.println("\nYou need to enter 'Y' or 'y' to shut down the RBL server.");
        }
      } catch (Exception e) {
        log.error("Error: {}", e.getMessage());
        if (log.isDebugEnabled())
          e.printStackTrace();
      }
    }
  }
}
TOP

Related Classes of org.jwall.rbl.net.AdminHandler

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.