/*
 *(c) 2003, visigoth <visigoth@securitycentric.com>
 * This source code is distributed under a BSD license,
 * please see the LICENSE file for details
 *
 * ConnectScanner.java
 *
 * Created on May 5, 2003, 7:26 AM
 */

import com.securitycentric.metacoretex.*;
import com.securitycentric.metacoretex.lib.*;
import com.securitycentric.metacoretex.interfaces.*;

import java.util.*;
import java.net.*;
import java.io.*;

/**
 *
 * @author  visigoth
 */
public class ConnectScanner extends AbstractProbe {
    
    /** Creates a new instance of ConnectScanner */
    public ConnectScanner() {
        
        setName("TCP Connect Scanner");
        setFamily("Network");
        setVersion("$Id: ConnectScanner.java,v 1.8 2003/09/30 20:06:13 visigoth_6 Exp $");
        setProbeId(1);
        setCopyright("(c) 2003, visigoth <visigoth@securitycentric.com>");
        
        addProvides("tcp/ports","Boolean tcp/<port> true = open, false = closed");
        
        addOption("tcp/min","1");
        addOption("tcp/max","4096");
        addOption("connect.timeout","0");
        
        setHelp("This probe does a vanilla TCP connect scan and "+
        "puts a Boolean object into the KB keyed by tcp/<portnum> "+
        "Probes may list themselvs dependant on tcp/ports and use "+
        "these Boolean objects to test if they should run\n\n"+
        "I promise I'll write a better port scanner soon!\n\n"+
        "Options:\n"+
        "tcp/min - The minimum port for the scan\n\n"+
        "tcp/max - The top port to scan\n\n"+
        "connect.timeout - Number of milliseconds to wait for a connection attempt (0 means infinite)\n\n");
        
        setReport("The Following open ports were detected: \n");
        setReportable(true);
    }
    
    public void probe() throws ProbeException {
        int optMin, optMax, timeout;
        
        try {
            optMin = Integer.parseInt(getOption("tcp/min"));
            optMax = Integer.parseInt(getOption("tcp/max"));
            timeout = Integer.parseInt(getOption("connect.timeout"));
            
        } catch (NumberFormatException ie) {
            throw(new ProbeException("User specified non-number where integer required"));
        }
        
        try {
            inAddr = InetAddress.getByName(getHost());
        } catch (UnknownHostException e) {
            throw(new ProbeException("Host Not Found! "+e.getMessage()));
        }
        
        for (port = optMin; port <= optMax; port++) {
            
            try {
                
                sock = new Socket();
                InetSocketAddress saddr = new InetSocketAddress(inAddr,port);
                sock.connect(saddr,timeout);
                kbPut( "tcp/" + String.valueOf(port), new Boolean(true));
                addReport(String.valueOf(port));
                
                //sock.close();
                
            } catch (IOException ie) {
                //This means no connect
                kbPut("tcp/" + String.valueOf(port), new Boolean(false));
            }
        }
    }
    
    Socket sock;
    InetAddress inAddr;
    int port;
}
