/*
 *(c) 2003, visigoth <visigoth@securitycentric.com>
 * This source code is distributed under a BSD license,
 * please see the LICENSE file for details
 *
 * OracleAuth.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.sql.*;
import java.util.*;

/**
 *
 * @author  visigoth
 */
public class OracleAuth extends AbstractProbe {
    
    /** Creates a new instance of OracleAuth */
    public OracleAuth() {
        
        setName("Oracle Authentication Tester");
        setFamily("Oracle");
        setCopyright("(c) 2003, visigoth <visigoth@securitycentric.com>");
        setVersion("$Id: OracleAuth.java,v 1.5 2003/10/02 02:20:43 visigoth_6 Exp $");
        setProbeId(5);
        
        addProvides("oracle/connection","java.sql.Connection to target Oracle");
        addProvides("oracle/user","String username for Oracle");
        addProvides("oracle/password","String password for Oracle");
        addProvides("oracle/sid","String SID for Oracle");
        
        addDepends("tcp/ports");
        
        addOption("oracle/user","scott");
        addOption("oracle/password","tiger");
        addOption("oracle/role","sysdba");
        addOption("oracle/sid","oracle");
        
        setHelp("This probe attempts to connect to an available Oracle database "+
                "using the user specified connection information.  Upon successful "+
                "connection, the probe will put the JDBC Connection object into the "+
                "KB under key oracle/connection\n\n"+
                "Options:\n"+
                "oracle/user - The username to use for connecting\n\n"+
                "oracle/password - The password to use for connecting\n\n"+
                "oracle/sid - The name of the database to connect to.  This Value can NOT be null\n\n"+
                "oracle/role - The role to attempt to connect as, this value may be null, which will make the connection not use a role at all\n\n");
        
        setReport("Could NOT connect to Oracle database");
    }
    
    /** Ok, this ones a little counterintuitive.  Return a true on
     *  a failure to connect so they report will show why all those
     *  other modules failed to connect
     */
    public void probe() throws ProbeException {
        
        if (kbHas("tcp/1521")) {
            Boolean bol = (Boolean)kbGet("tcp/1521");
            if ( ! bol.booleanValue())
                return;
        }
        
        Properties prop = new Properties();
        
        prop.setProperty("user",getOption("oracle/user"));
        prop.setProperty("password",getOption("oracle/password"));
        prop.setProperty("internal_logon",getOption("oracle/role"));
        
        try {
            Class.forName("oracle.jdbc.driver.OracleDriver");
        } catch (ClassNotFoundException ce) {
            throw(new ProbeException("Oracle Driver not installed?"));
        }
        
        
        try {
            con = DriverManager.getConnection("jdbc:oracle:thin:@" + getHost() + ":1521:" + getOption("oracle/sid"), prop);
        } catch (SQLException se) {

            if (se.getMessage().startsWith("ORA-01017")) {
                setReport(se.getMessage());
                setSeverity(3);
                setReportable(true);
                return;
            }

            throw(new ProbeException("SID Invalid/Not Running: " + se.getMessage()));
        }
        
        kbPut("oracle/user",getOption("oracle/user"));
        kbPut("oracle/password",getOption("oracle/password"));
        kbPut("oracle/role",getOption("oracle/role"));
        kbPut("oracle/sid",getOption("oracle/sid"));
        kbPut("oracle/connection",con);
        
        // If we connected as sysba, let the other probes know
        if (((String)getOption("oracle/role")).matches("sysdba"))
            kbPut("oracle/sysdba","sysdba");
    }
    
    Connection con;
}
