Package org.jwall.rbl.net

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

/*******************************************************************************
* 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;


/**
* <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 {

  /* 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;
  }


  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" ) ) {
          RblServer.log.info( "Client connect from {} rejected. Allowing localhost connections only!", client.getInetAddress().getHostAddress() );
          client.close();
          return;
        }
        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;
    Socket socket;
    boolean running = true;

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

    public void run(){

      try {
        BufferedReader r = 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 = r.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;
      }
     
      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();
      }
    }
  }
}
TOP

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

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.