#!/usr/bin/env python2

"""
Module Informix database information gather for Inguma
Copyright (c) 2008 Joxean Koret <joxeankoret@yahoo.es>

License is GPL
"""

import sys
import socket

from lib.libexploit import CIngumaModule
from lib.libinformix import *

name = "ifxinfo"
brief_description = "Gather information from an Informix database server"
type = "gather"

globals = ["database", ]

class CInformixGather(CIngumaModule):
    
    informixResponse = None
    informixDatabases = None
    user = ""
    password = ""
    database = ""
    
    def help(self):
        """ This is the entry point for info <module> """
        print "target = <target host or network>"
        print "port = <target port>"
        print "timeout = <timeout>"

    def run(self):

        self.informixResponse = None
        self.informixDatabases = None

        if self.target == "":
            print "No target specified"
            return False

        if self.port == 0 or self.port == None:
            print "[!] Warning! Using port 9088"
            self.port = 9088

        ifx = Informix()
        ifx.username = self.user
        ifx.password = self.password

        if self.database == "":
            ifx.databaseName = ""
        else:
            ifx.databaseName = self.database

        socket.setdefaulttimeout(self.timeout)
        try:
            s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            s.connect((self.target, self.port))
        except:
            print sys.exc_info()[1]
            return False

        buf = ifx.getPacket()
        print "[+] Sending login packet (User: %s, Password %s, Database: %s)" % (ifx.username,  ifx.password,  ifx.databaseName)
        s.send(buf)
        data = s.recv(4096)
        print "[+] Received %d byte(s)" % len(data)
        self.informixResponse = InformixLoginResponse()
        self.informixResponse.parse(data)

        print "[+] Searching databases ... "
        ifxCmd = InformixCommand()
        ifxCmd.opcode = IFX_OPCODE_DBLIST
        buf = ifxCmd.getPacket()
        print "[+] Sending DBLIST command ... "
        s.send(buf)
        print "[+] Receiving list of databases ... "
        data = s.recv(4096)

        self.informixDatabases = InformixDbListResponse()
        self.informixDatabases.databases = []
        self.informixDatabases.parse(data)

        return True

    def printSummary(self):
        print "[+] Gathered information from Informix Database Server"
        print
        print "    Is valid user".ljust(18),  repr(self.informixResponse.isValidUser)
        self.addToDict(self.target + "_informix",  {"ValidUser":self.informixResponse.isValidUser})

        if self.database != "":
            print "    Is valid db".ljust(18),  repr(self.informixResponse.isValidDatabase)
            self.addToDict(self.target + "_informix",  {"ValidDatabase":self.informixResponse.isValidDatabase})

        print "    IEEE".ljust(18),  repr(self.informixResponse.ieee)
        self.addToDict(self.target + "_informix",  {"IEEE":self.informixResponse.ieee})
        print "    Name".ljust(18),  repr(self.informixResponse.name)
        self.addToDict(self.target + "_informix",  {"Name":self.informixResponse.name})
        print "    Banner".ljust(18),  repr(self.informixResponse.banner)
        self.addToDict(self.target + "_informix",  {"Banner":self.informixResponse.banner})
        print "    Serial Number".ljust(18),  repr(self.informixResponse.serialNumber)
        self.addToDict(self.target + "_informix",  {"SerialNumber":self.informixResponse.serialNumber})
        print "    Db Path".ljust(18),  repr(self.informixResponse.databasePath)
        self.addToDict(self.target + "_informix",  {"DBPath":self.informixResponse.databasePath})
        print "    Protocol".ljust(18),  repr(self.informixResponse.protocol)
        self.addToDict(self.target + "_informix",  {"Protocol":self.informixResponse.protocol})
        print "    Hostname".ljust(18),  repr(self.informixResponse.hostname)
        self.addToDict(self.target + "_informix",  {"Hostname":self.informixResponse.hostname})
        print "    Terminal".ljust(18),  repr(self.informixResponse.terminal)
        self.addToDict(self.target + "_informix",  {"Terminal":self.informixResponse.terminal})
        print "    Home Path".ljust(18),  repr(self.informixResponse.homePath)
        self.addToDict(self.target + "_informix",  {"HomePath":self.informixResponse.homePath})
        print
        print "Discovered databases"
        print "--------------------"
        print
        for db in self.informixDatabases.databases:
            print "    %s" % db
            self.addToDict(self.target + "_informix", {"Database":db})
        print

