/*
 * (c) 2003, visigoth <visigoth@securitycentric.com>
 * This source code is distributed under a BSD license.
 * Please see the LICENSE file for details.
 *
 * OracleTNSStatus.java
 *
 * Created on May 4, 2003, 8:03 AM
 */

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

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

/**
 *
 * @author  visigoth
 */
public class OracleTNSStatus extends AbstractDatabaseProbe {
    
    /** Creates a new instance of OracleSids */
    public OracleTNSStatus() {
        setName("Oracle TNS Status");
        setFamily("Oracle");
        setCopyright("(c) 2003, visigoth <visigoth@securitycentric.com>");
        setVersion("$Id: OracleTNSStatus.java,v 1.4 2003/09/21 22:44:11 visigoth_6 Exp $");
        setProbeId(11);

        setHelp("This probe gets the TNS status string from the TNSListener\n\n"+
                "Options:\n"+
                "oracle.tns.password - Password for the tnslsnr service (can, and usually is blank)\n\n"+
                "port - Port for the TNSLSNR service. Default = 1521\n\n"+
                "wait - Time (seconds) to wait for the complete response (default 3) if you are getting no SIDS and no Exception, maybe make this higher\n\n");
        
        addDepends("tcp/ports");

        addProvides("oracle/status","String of TNS status response");

        addOption("oracle.tns.password","");
        addOption("port","1521");
        addOption("wait","3");
    }
    
    public void probe() throws ProbeException {

        /* Don't try if our port isn't open */
        if (kbHas("tcp/"+getOption("port"))) {
            Boolean bol = (Boolean)kbGet("tcp/"+getOption("port"));
            if (! bol.booleanValue()) {
                return;
            }
        }

        String pass = (String)getOption("oracle.tns.password");


        headr[1] =  headr.length + command.length();
        headr[25] =  command.length();

        try {

            port = Integer.parseInt(getOption("port"));
            sleep = Integer.parseInt(getOption("wait"));

            soc = new Socket(getHost(), port);
            inStream = new BufferedInputStream( soc.getInputStream());
            outStream = new BufferedOutputStream( soc.getOutputStream());

            for (int i = 0; i < headr.length; i++)
                outStream.write(headr[i]);

            outStream.write(command.getBytes());
            outStream.flush();

            Thread.sleep(sleep * 1000);
            
            resp = new byte[inStream.available()];
            inStream.read(resp);

            setReportable(true);

            if (resp[4] != 2)
                throw(new ProbeException("TNS Status Command Rejected"));

            respStr = new String(resp,"US-ASCII").trim().replaceAll("\\p{Cntrl}",".");

            setReport("The following is the entire status response:\n\n" + respStr);

            kbPut("oracle/status",respStr);

        } catch (IOException ie) {
            throw(new ProbeException(ie.getMessage()));
        } catch (InterruptedException ie) {
            throw(new ProbeException(ie.getMessage()));
        } catch (NumberFormatException ne) {
            throw(new ProbeException("Bad Number Option"));
        }
    }

    byte resp[];

    /*
    int headr[] = {
    0x00, 0x59, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
    0x01, 0x36, 0x01, 0x2c, 0x00, 0x00, 0x08, 0x00,
    0x7f, 0xff, 0x7f, 0x08, 0x00, 0x00, 0x00, 0x01,
    0x00, 0x1f, 0x00, 0x3a, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x34, 0xe6, 0x00, 0x00,
    0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x28, 0x43, 0x4f, 0x4e, 0x4e, 0x45,
    0x43, 0x54, 0x5f, 0x44, 0x41, 0x54, 0x41, 0x3d,
    0x28, 0x43, 0x4f, 0x4d, 0x4d, 0x41, 0x4e, 0x44,
    0x3d, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x29,
    0x29 };
    */

    int headr[] = {
    0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
    0x01, 0x36, 0x01, 0x2c, 0x00, 0x00, 0x08, 0x00,
    0x7f, 0xff, 0x7f, 0x08, 0x00, 0x00, 0x00, 0x01,
    0x00, 0x00, 0x00, 0x3a, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x34, 0xe6, 0x00, 0x00,
    0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00};


    String command = "(CONNECT_DATA=(COMMAND=status))";

    String respStr;

    int port,sleep;
    Socket soc;
    BufferedInputStream inStream;
    BufferedOutputStream outStream;
}
