/*
 *(c) 2003, visigoth <visigoth@securitycentric.com>
 * This source code is distributed under a BSD license,
 * please see the LICENSE file for details
 *
 * MysqlAuth.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 MysqlAuth extends AbstractProbe {
    
    /** Creates a new instance of MysqlAuth */
    public MysqlAuth() {
        
        setName("MySQL Authentication");
        setFamily("MySQL");
        setProbeId(3);
        setCopyright("(c) 2003, visigoth <visigoth@securitycentric.com>");
        setVersion("$Id: MysqlAuth.java,v 1.5 2003/10/02 02:20:43 visigoth_6 Exp $");
        
        setHelp("This probe attempts to connect to an available MySQL database "+
                "using the user specified connection information.  Upon successful "+
                "connection, the probe will put the JDBC Connection object into the "+
                "KB under key mysql/connection\n\n"+
                "Options:\n"+
                "mysql/user - The username to use for connecting\n\n"+
                "mysql/password - The password to use for connecting\n\n"+
                "mysql/db - The name of the database to connect to.  This "+
                "value can be null, but then later DB specific probes may not "+
                "get table information\n\n");
        
        addProvides("mysql/connection","java.sql.Connection to the target MySQL instance"); 

        addDepends("tcp/ports");
        
        addOption("mysql/user","root");
        addOption("mysql/password","");
        addOption("mysql/db","mysql");
        
        setReport("Could NOT connect to MySQL 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 we know the port's closed, return false
        if (kbHas("tcp/3306")) {
            Boolean bol = (Boolean)kbGet("tcp/3306");
            
            if(!bol.booleanValue()) 
                return;
        }
        
        try {
            Class.forName("com.mysql.jdbc.Driver");
        } catch (ClassNotFoundException ce) {
            throw(new ProbeException("MySQL Driver not installed?"));
        }
        
        try {
            con = DriverManager.getConnection("jdbc:mysql://" + getHost() + "/" + getOption("mysql/db"), getOption("mysql/user"), getOption("mysql/password"));
        } catch (SQLException se) {
            
            /* This should sort out connection errors vs auth errors
             */
            if (se.getMessage().matches(".*denied.*")) {
                setSeverity(3);
                setReport("Username/Password Failure");
                setReportable(true);
                return;
            } else {
                throw(new ProbeException(se.getMessage()));
            }
        }
        
        
        kbPut("mysql/user",getOption("mysql/user"));
        kbPut("mysql/password",getOption("mysql/password"));
        kbPut("mysql/connection",con);
    }
    
    String name, pass;
    Connection con;
}
