#!/usr/bin/env python


import logging
import time

from optparse import OptionParser
from optparse import OptionError

from lib import log
from lib.common import version
from lib.option import Option
from lib.injection import Injection


def showBanner():
    """
    This function prints sqlmap banner with its version
    """

    print """
    sqlmap/%s coded by inquis <bernardo.damele@gmail.com>
                    and belch <daniele.bellucci@gmail.com>
    """ % version


def parseArgs():
    """
    This function parses the command line parameters and arguments
    """

    parser = OptionParser()

    try:
        parser.add_option("-u", "--url",
                          dest="url",
                          help="target url")

        parser.add_option("-p",
                          dest="urlParameter",
                          help="specify the testable parameter(s)")

        parser.add_option("-g",
                          dest="googleDork",
                          help="rather than providing a target url, "
                               "let Google return target hosts as "
                               "result of your Google dork expression")

        parser.add_option("-a",
                          dest="userAgentsFile",
                          help="load a random HTTP User-Agent "
                               "header from file")

        parser.add_option("--method",
                          dest="httpMethod",
                          help="HTTP method, GET or POST "
                               "(default: GET)")

        parser.add_option("--data",
                          dest="data",
                          help="data string to be sent through POST")

        parser.add_option("--basic-auth",
                          dest="bAuth",
                          help="HTTP Basic Authentication, value: "
                               "'username:password'")

        parser.add_option("--digest-auth",
                          dest="dAuth",
                          help="HTTP Digest Authentication, value: "
                               "'username:password'")

        parser.add_option("--cookie",
                          dest="cookie",
                          help="HTTP Cookie header")

        parser.add_option("--proxy",
                          dest="proxy",
                          help="use a proxy to connect to the "
                               "target url")

        parser.add_option("--string",
                          dest="string",
                          help="string to match in page "
                               "when the query is valid")

        parser.add_option("--remote-dbms",
                          dest="dbms",
                          help="perform checks only for this specific "
                               "DBMS ('MySQL', 'PostgreSQL' or 'Microsoft "
                               "SQL Server')")

        parser.add_option("-f", "--fingerprint",
                          dest="exaustiveFp",
                          action="store_true",
                          help="perform an exaustive database fingerprint")

        parser.add_option("-b", "--banner",
                          dest="getBanner",
                          action="store_true",
                          help="get DBMS banner")

        parser.add_option("--current-user",
                          dest="getCurrentUser",
                          action="store_true",
                          help="get current DBMS user")

        parser.add_option("--current-db",
                          dest="getCurrentDb",
                          action="store_true",
                          help="get current DBMS name")

        parser.add_option("--users",
                          dest="getUsers",
                          action="store_true",
                          help="get DBMS users")

        parser.add_option("--passwords",
                          dest="getPasswordHashes",
                          action="store_true",
                          help="get DBMS users password hashes")

        parser.add_option("--dbs",
                          dest="getDbs",
                          action="store_true",
                          help="get available databases")

        parser.add_option("--tables",
                          dest="getTables",
                          action="store_true",
                          help="get database tables "
                               "(optional: -D)")

        parser.add_option("--columns",
                          dest="getColumns",
                          action="store_true",
                          help="get table columns "
                               "(required: -T optional: -D)")

        parser.add_option("--dump",
                          dest="dumpTable",
                          action="store_true",
                          help="dump a database table content "
                               "(required: -T optional: -D and -C)")

        parser.add_option("--file",
                          dest="filename",
                          help="read a specific file content")

        parser.add_option("-e",
                          dest="expression",
                          help="expression to evaluate")

        parser.add_option("--union-check",
                          dest="unionCheck",
                          action="store_true",
                          help="check for UNION SELECT statement")

        parser.add_option("--union-use",
                          dest="unionUse",
                          action="store_true",
                          help="use the UNION SELECT statement to "
                               "retrieve the output of your expression "
                               "(required: -e or --file)")

        parser.add_option("-D", "--database",
                          dest="db",
                          help="database to enumerate")

        parser.add_option("-T", "--table",
                          dest="tbl",
                          help="database table to enumerate")

        parser.add_option("-C", "--column",
                          dest="col",
                          help="database table column to enumerate")

        parser.add_option("-v", "--verbose",
                          dest="verbose",
                          help="set verbosity level (0-2), "
                               "default is 0")

        parser.add_option("-o",
                          dest="outputFile",
                          help="save all data retrieved on a text file")

        parser.add_option("-r", "--resume",
                          dest="resume",
                          action="store_true",
                          help="resume queries value using "
                               "a text file as input")

        (args, options) = parser.parse_args()

        if not args.url and not args.googleDork:
            parser.error("missing a mandatory parameter ('-u' or '-g')")
        elif args.verbose and args.verbose not in ("0", "1", "2"):
            parser.error("verbose must be a digit between 0 and 2")

        return args
    except (OptionError, TypeError), e:
        parser.error(e)


def main():
    """
    This is the main function of sqlmap. It is called at each
    run of the program
    """

    logger = logging.getLogger("sqlmapLog")

    showBanner()
    shellArgs = parseArgs()

    print "[*] starting at: %s\n" % time.strftime("%X")

    try:
        optObj = Option()
        checkedArgs = optObj.run(shellArgs)

        injObj = Injection()
        injObj.run(checkedArgs)
    except Exception, e:
        logger.error(str(e))

    print "[*] shutting down at: %s\n" % time.strftime("%X")


if __name__ == "__main__":
    main()

