# -*- coding: utf-8 -*-
"""
Inguma Penetration Testing Toolkit
Copyright (c) 2006, 2007 Joxean Koret, joxeankoret [at] yahoo.es

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; version 2
of the License.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
"""
import os
import sys
#import thread
import signal

# Import base module and specify that will be running in GUI mode
import inguma
inguma.isGui = True
inguma.user_data["isGui"] = True
inguma.user_data["interactive"] = False

# Fix for bug 1807529 (andresriancho)
inguma.user_data["base_path"] = '.'

from qt import *
from fmmainui import *
from dlgabout import dlgAboutUi

sys.path.append("../lib")
sys.path.append("../../lib")
sys.path.append("lib")

from printwrapper import CPrintWrapper

lastThread = None
dlg = None

class IngumaModuleThread(QThread):

    function = None
    arguments = None

    def __init__(self):
        QThread.__init__(self)

    def run(self):
        self.function(self.arguments)

class MyListItem(QListViewItem):

    def paintCell(self, p, cg, column, width, align ):
        if self.text(1).find("[0day]") > -1:
            cg = QColorGroup(cg)
            cg.setColor(QColorGroup.Text, QColor("red"))
        QListViewItem.paintCell(self, p, cg, column,width,align)

class frmMain(fmMain):

    selected = None
    oldFile = None
    errFile = None
    
    def __del__(self):
        pass

    def showElements(self):
        inguma.readCommands()
        inguma.interactive = False

        oldElement = None
        it = QListViewItemIterator(self.lstModules)
        it.current()

        x = MyListItem(self.lstModules, "Autoscan")
        x.setText(1, "Autoscan the selected target")

        parent = MyListItem(self.lstModules, "1) Discover")
        for element in inguma.discovers:
            x = MyListItem(parent, element.name)
            x.setText(1, element.brief_description)

        parent = MyListItem(self.lstModules, "2) Gather")
        for element in inguma.gathers:
            x = MyListItem(parent, element.name)
            x.setText(1, element.brief_description)

        parent = MyListItem(self.lstModules, "3) Brute force")
        for element in inguma.brutes:
            x = MyListItem(parent, element.name)
            x.setText(1, element.brief_description)

        parent = MyListItem(self.lstModules, "4) Exploits")
        for element in inguma.exploits:
            x = MyListItem(parent, element.name)
            x.setText(1, element.brief_description)

        return

    def loadUserPasswords(self):
        users = file(inguma.user_data["base_path"] + "/data/users", "r").readlines()

        self.cbUsername.insertItem("")
        for user in users:
            self.cbUsername.insertItem(user.strip("\r").strip("\n"))

        passwds = file(inguma.user_data["base_path"] + "/data/dict", "r").readlines()

        self.cbPassword.insertItem("")
        for passwd in passwds:
            self.cbPassword.insertItem(passwd.strip("\r").strip("\n"))

    def fileOpen(self):
        print "fmMain.fileOpen(): Not implemented yet"

    def fileSave(self):
        print "fmMain.fileSave(): Not implemented yet"

    def fileSaveAs(self):
        print "fmMain.fileSaveAs(): Not implemented yet"

    def fileExit(self):
        self.close()

    def read(self, text):
        return "1"

    def write(self, text):
        self.txtLog.setText(str(self.txtLog.text()) + text)
        self.txtLog.scrollToBottom()

    def readOptions(self):
        inguma.target = str(self.cbTarget.currentText())
        inguma.port = int(self.cbPort.value())
        return
        print "Port: %d" % inguma.port
        inguma.timeout = int(self.txtTimeout.value())
        print "Timeout: %d" % inguma.timeout
        inguma.user = str(self.cbUsername.currentText())
        print "User: %s" % inguma.user
        inguma.password = str(self.cbPassword.currentText())
        print "Password: %s" % inguma.password
        inguma.dad = str(self.txtDad.text())
        print "DAD: %s" % inguma.dad
        inguma.sid = str(self.txtSid.text())
        print "SID: %s" % inguma.sid

    def internalRunModule(self, module):
        global lastThread

        self.readOptions()
        self.txtLog.setText(str(self.txtLog.text()) + os.linesep + "[+] Running module '" + module + "'" + os.linesep)

        self.oldFile = sys.stdout
        self.errFile = sys.stderr

        sys.stdout = self
        sys.stderr = self

        self.cmdRun.setEnabled(False)

        print
        try:
            if module.lower() != "autoscan":
                inguma.runRegisteredCommand(module)
            else:
                inguma.doAutoScan()
        except:
            print "Error:", sys.exc_info()[1]

        self.tabInformation_selected(None)
        self.cmdRun.setEnabled(True)

        sys.stdout = self.oldFile
        sys.stderr = self.errFile
        lastThread = None

    def runModule(self):
        global lastThread

        __builtins__["raw_input"] = self.myraw_input
        list = str(self.txtIgnoreHosts.text()).split(";")
        
        if len(list) == 0:
            list = list[0]

        if len(list) > 0:
            inguma.user_data["ignore_host"] = list

        if lastThread == None:
            lastThread = IngumaModuleThread()
            lastThread.function = self.internalRunModule
            lastThread.arguments = str(self.selected.text(0))
            lastThread.start()
            #lastThread = thread.start_new_thread(self.internalRunModule, (str(self.selected.text(0)), ))
        else:
            # Fix for bug 1807536 (andresriancho)
            self.txtLog.setText(str(self.txtLog.text()) + os.linesep + str("[!] There is a module running, wait!"))

    def cmdRun_clicked(self):
        self.runModule()

    def cmdKill_clicked(self):
        global lastThread
        
        if lastThread != None:
            lastThread.terminate()
            lastThread = None
            print "Thread killed"
            sys.stderr = self.errFile
            sys.stdout = self.oldFile
            self.cmdRun.setEnabled(True)

    def lstModules_doubleClicked(self,item):
        self.runModule()

    def lstModules_clicked(self, item):
        self.selected = item
        if not item:
            return

        if item.text(0).find(")") > -1:
            self.cmdRun.setEnabled(False)
        else:
            self.cmdRun.setEnabled(True)

    def tabInformation_selected(self,a0):
        buf = ""
        for x in inguma.user_data:
            if x != "ports":
                buf += x + "=" + str(inguma.user_data[x]) + os.linesep

        self.txtKb.setText(buf)

    def myraw_input(self, text):
        a = QInputDialog.getText("Inguma",
                "mierda",
                QLineEdit.Normal)
        raise "The function 'raw_input' is currently disabled in the QT Gui. To use the module try running the text version instead."

    def cbTarget_textChanged(self, text):
        if not self.isShown(): return
        inguma.target = str(text)
        inguma.user_data["target"] = str(text)

    def cbPort_valueChanged(self, ivalue):
        if not self.isShown(): return
        inguma.port = ivalue
        inguma.user_data["port"] = str(ivalue)

    def txtTimeout_valueChanged(self, ivalue):
        if not self.isShown(): return
        inguma.timeout = ivalue
        inguma.user_data["timeout"] = str(ivalue)
    
    def cbUsername_textChanged(self, text):
        if not self.isShown(): return
        inguma.user = str(text)
        inguma.user_data["user"] = str(text)
        
    def cbPassword_textChanged(self, text):
        if not self.isShown(): return
        inguma.password = str(text)
        inguma.user_data["password"] = str(text)
    
    def txtSid_textChanged(self, text):
        if not self.isShown(): return
        inguma.sid = str(text)
        inguma.user_data["sid"] = str(text)
    
    def txtDad_textChanged(self, text):
        if not self.isShown(): return
        inguma.dad = str(text)
        inguma.user_data["dad"] = str(text)
    
    def chkSsl_stateChanged(self, ivalue):
        if not self.isShown(): return
        inguma.ssl = bool(ivalue)
        inguma.user_data["ssl"] = bool(ivalue)
    
    def menuAboutToShow(self):
        global dlg
        
        if dlg == None:
            dlg = dlgAboutUi()

        dlg.show()

    def txtIgnoreHosts_textChanged(self, text):
        pass

    def editClear_Output_BoxAction_activated(self):
        # Fix for bug 1807537 (andresriancho)
        self.txtLog.setText("")

    def cboCommands_activated(self, text):
        global lastThread

        __builtins__["raw_input"] = self.myraw_input
        list = str(self.txtIgnoreHosts.text()).split(";")

        if len(list) == 0:
            list = list[0]

        if len(list) > 0:
            if inguma.user_data.has_key("ignore_host"):
                inguma.user_data["ignore_host"].append(list)
            else:
                inguma.user_data["ignore_host"] = list

        if lastThread == None:
            lastThread = IngumaModuleThread()
            lastThread.function = self.internalRunInterfaceModule
            lastThread.arguments = str(text)
            lastThread.start()
            #lastThread = thread.start_new_thread(self.internalRunModule, (str(self.selected.text(0)), ))
        else:
            # Fix for bug 1807536 (andresriancho)
            self.txtLog.setText(str(self.txtLog.text()) + os.linesep + str("[!] There is a module running, wait!"))

    def internalRunInterfaceModule(self, module):
        global lastThread

        self.readOptions()
        self.txtLog.setText(str(self.txtLog.text()) + os.linesep + "inguma> '" + module + "'" + os.linesep)

        self.oldFile = sys.stdout
        self.errFile = sys.stderr

        sys.stdout = self
        sys.stderr = self

        self.cmdRun.setEnabled(False)

        try:
            inguma.runInterfaceCommand(module)
        except:
            print "Error:", sys.exc_info()[1]

        self.tabInformation_selected(None)
        self.cmdRun.setEnabled(True)

        sys.stdout = self.oldFile
        sys.stderr = self.errFile
        lastThread = None
