/***************************************************************************
 *   Copyright (C) 2011 by Francesco Cecconi                               *
 *   francesco.cecconi@gmail.com                                           *
 *                                                                         *
 *   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; either 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.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/

#include "vulnerability.h"
#include "mainwin.h"

vulnerability::vulnerability(nmapClass* parent) : QObject(parent), _ui(parent)
{
    setupActions();
    
    connect(_ui->tWresult, SIGNAL(tabCloseRequested(int)),
            this,SLOT(closeVulnTab(int)));
    connect(_ui->comboVulnRis->lineEdit(), SIGNAL(returnPressed()),
            this, SLOT(searchVulnerability()));
    connect(_ui->addUrlButt, SIGNAL(clicked()),
            this, SLOT(startAddUrl_ui()));
    connect(_ui->removeUrlButt, SIGNAL(clicked()),
            this, SLOT(removeUrlToBookmarks()));
    connect(_ui->comboVulnRis->lineEdit(), SIGNAL(cursorPositionChanged(int,int)),
            this, SLOT(updateFontHostVuln()));
    connect(_ui->comboVuln, SIGNAL(currentIndexChanged(QString)),
            this, SLOT(updateComboVuln(QString)));
}

vulnerability::~vulnerability()
{
    freelist<QWebView*>::itemDeleteAll(_webViewList);
    freemap<QString,QAction*>::itemDeleteAll(_collections);
}

void vulnerability::setupActions()
{
    /**
     * Setup actions for vulnerability section
     */
    QAction* action;
    
    action = new QAction(this);
    action->setIcon(QIcon(QString::fromUtf8(":/images/images/viewmag.png")));
    action->setIconText(tr("Search"));
    action->setEnabled(false);
    _collections.insert("search-act",action);
    connect(action, SIGNAL(triggered()),this, SLOT(searchVulnerability()));
    _ui->toolBarSearch->addAction(action);

    action = new QAction(this);
    action->setIcon(QIcon(QString::fromUtf8(":/images/images/left.png")));
    action->setIconText(tr("Back"));
    action->setEnabled(false);
    _collections.insert("back-act",action);
    connect(action, SIGNAL(triggered()),this, SLOT(tabWebBack()));
    _ui->toolBarSearch->addAction(action);

    action = new QAction(this);
    action->setIcon(QIcon(QString::fromUtf8(":/images/images/right.png")));
    action->setIconText(tr("Forward"));
    action->setEnabled(false);
    _collections.insert("forward-act",action);
    connect(action, SIGNAL(triggered()),this, SLOT(tabWebForward()));
    _ui->toolBarSearch->addAction(action);

    action = new QAction(this);
    action->setIcon(QIcon(QString::fromUtf8(":/images/images/button_cancel.png")));
    action->setIconText(tr("Stop"));
    action->setEnabled(false);
    _collections.insert("stop-act",action);
    connect(action, SIGNAL(triggered()),this, SLOT(tabWebStop()));
    _ui->toolBarSearch->addAction(action);

    _ui->toolBarSearch->setContextMenuPolicy(Qt::PreventContextMenu);
}


QHash<QString, QString> vulnerability::getDefaultUrlList() const
{
    // define a QHash with static url Name + url
    QHash<QString, QString> urlMap_;
    
    // set default name+value url
    urlMap_.insert("www.securityfocus.com",
                   "http://www.securityfocus.com/swsearch?sbm=bid&submit=Search%21&metaname=alldoc&sort=swishrank&query=");
    urlMap_.insert("cve.mitre.org","http://cve.mitre.org/cgi-bin/cvekey.cgi?keyword=");
    urlMap_.insert("secunia.com","http://secunia.com/advisories/search/?search=");
    urlMap_.insert("web.nvd.nist.gov","http://web.nvd.nist.gov/view/vuln/search-results?search_type=all&cves=on&query=");
    
    return urlMap_;

}

void vulnerability::searchVulnerability()
{
        if (_ui->comboVulnRis->currentText().isEmpty())
    {
        return;
    }

    // save current search on history
    logHistory *history = new logHistory("nmapsi4/cacheVuln", _ui->hostCache);
    history->addItemHistory(_ui->comboVulnRis->currentText());
    delete history;
    //update completer cache
    _ui->updateCompleter();
    // default action settings
    _collections.value("search-act")->setEnabled(false);
    _collections.value("stop-act")->setEnabled(true);
    _collections.value("back-act")->setEnabled(true);
    _collections.value("forward-act")->setEnabled(true);

    QString finalUrlString;
    QString tmpSearchString;
    // search string from QComboBox
    tmpSearchString = _ui->comboVulnRis->currentText();
    // space to + for correct search string format
    tmpSearchString.replace(QString(" "), QString("+"));

    // create QHash for default profile
    QHash<QString, QString> tmpUrlMap = getDefaultUrlList();
    
    // selection url from key for search
    if (_ui->comboWebV->currentIndex() < tmpUrlMap.size()) 
    {
        // It is a default url, stored in QHash
        finalUrlString = tmpUrlMap.value(_ui->comboWebV->currentText());
    } 
    else 
    {
        // It isn't a default url, but an url from treeWidget
        QList<QTreeWidgetItem *> resultList_ = _ui->treeWidgetVulnUrl->findItems(_ui->comboWebV->currentText(),Qt::MatchExactly,0);
        finalUrlString = resultList_[0]->text(1);
    }
    
    finalUrlString.append(tmpSearchString);
    
    QUrl urlFinal(finalUrlString);

    // make tabBar visible for the first search
    if(!_webViewList.size()) 
    {
        _ui->tWresult->setVisible(true);
    } 

    // create new tab with a QWebView
    QWebView *page = new QWebView();
    _webViewList.push_back(page);
    page->load(urlFinal);
    _ui->tWresult->addTab(page,_ui->comboVulnRis->currentText());
    connect(page, SIGNAL(loadProgress(int)),_ui->progressWeb, SLOT(setValue(int)));
    connect(page, SIGNAL(loadFinished(bool)),this, SLOT(vulnPostScan()));
}

void vulnerability::closeVulnTab(int index) 
{
    QWebView *page = _webViewList.takeAt(index);
    _ui->tWresult->removeTab(index);
    delete page;
    
    if (!_webViewList.size())
    {
        _ui->tWresult->setVisible(false);
    }
}

void vulnerability::tabWebBack() 
{
    _webViewList[_ui->tWresult->currentIndex()]->triggerPageAction(QWebPage::Back);
}

void vulnerability::tabWebForward() 
{
    _webViewList[_ui->tWresult->currentIndex()]->triggerPageAction(QWebPage::Forward);
}

void vulnerability::tabWebStop() 
{
    _webViewList[_ui->tWresult->currentIndex()]->triggerPageAction(QWebPage::Stop);
}

void vulnerability::vulnPostScan() 
{
    _collections.value("search-act")->setEnabled(true);
    _collections.value("stop-act")->setEnabled(false);
}

void vulnerability::callVulnCheck()
{
    _ui->comboVulnRis->clear();
    _ui->comboVulnRis->insertItem(0,_ui->treeBookVuln->currentItem()->text(0));
    _ui->tabVuln->setCurrentIndex(0);
    searchVulnerability();
}

void vulnerability::callSearchHistoryVuln() 
{
    if (!_ui->actionAdd_Bookmark->isEnabled()) 
    {
        _ui->actionAdd_Bookmark->setEnabled(true);
        _ui->action_Add_BookmarkToolBar->setEnabled(true);
    }


    if (!_ui->_vulnModel)
    {
        return;
    }

    if (!_ui->_completerVuln)
    {
        _ui->_completerVuln = new QCompleter(_ui->_vulnModel);
        _ui->_completerVuln->setCompletionRole(QCompleter::InlineCompletion);
        _ui->_completerVuln->setWrapAround(false);
        _ui->_completerVuln->setCaseSensitivity(Qt::CaseInsensitive);
        _ui->comboVulnRis->setCompleter(_ui->_completerVuln);
    }
}

void vulnerability::updateComboVuln(const QString& value) 
{
    _ui->comboVulnRis->clear();

    if(_ui->comboVuln->currentIndex()) 
    {
        _ui->comboVulnRis->insertItem(0,value);
    } 
    else 
    {
        _ui->comboVulnRis->lineEdit()->clear();
    }

}

void vulnerability::objVulnButton() 
{ // SLOT
    _ui->comboVulnRis->clear();
    
    QString tmpServices_ = _ui->GItree->currentItem()->text(0);
    QList<QTreeWidgetItem*> itemList = _ui->listWscan->findItems(tmpServices_, Qt::MatchExactly, 2);

    if(_ui->comboVulnRis->itemText(0).isEmpty())
    {
        _ui->comboVulnRis->addItem(itemList[0]->text(3));
    } 
    else 
    {
        _ui->comboVulnRis->setItemText(0,itemList[0]->text(3));
    }

    _ui->_collectionsButton.value("scan-sez")->setChecked(false);
    _ui->_collectionsButton.value("log-sez")->setChecked(false);
    _ui->_collectionsButton.value("vuln-sez")->setChecked(true);
    _ui->_collectionsButton.value("discover-sez")->setChecked(false);

    _ui->toolBar->setVisible(false);
    _ui->toolBarBook->setVisible(true);
    _ui->toolBar_2->setVisible(false);
    _ui->toolBarSearch->setVisible(true);

    _ui->tabUi->removeTab(_ui->tabUi->indexOf(_ui->tabSOpt));
    _ui->tabUi->removeTab(_ui->tabUi->indexOf(_ui->tabNseOpt));
    _ui->tabUi->removeTab(_ui->tabUi->indexOf(_ui->tabScan));
    _ui->tabUi->removeTab(_ui->tabUi->indexOf(_ui->tabLog));
    _ui->tabUi->removeTab(_ui->tabUi->indexOf(_ui->tabDiscover));
    _ui->tabUi->insertTab(0,_ui->tabVulnMain,QIcon(QString::fromUtf8(":/images/images/viewmag+.png")),"Vulnerability");
    _ui->tabUi->setCurrentIndex(0);

    // disable scan action
    _ui->toolBarTab->setVisible(false);
}

void vulnerability::updateComboWebV() 
{
    // clear comboWeb
    _ui->comboWebV->clear();   
    // insert default static url in comboWeb
    QHash<QString, QString> tmpStaticProfileUrl_ = getDefaultUrlList();
    QHash<QString, QString>::const_iterator i;
    for (i = tmpStaticProfileUrl_.constBegin(); i != tmpStaticProfileUrl_.constEnd(); ++i) 
    {
        _ui->comboWebV->insertItem(1, i.key());
    }
    
    // value from treeWidget url
    for(int index=0; index < _ui->treeWidgetVulnUrl->topLevelItemCount(); index++) 
    {
        _ui->comboWebV->insertItem(3, _ui->treeWidgetVulnUrl->topLevelItem(index)->text(0));
    }
    
}

void vulnerability::startAddUrl_ui() 
{   
    mainUrlClass dialogUrl_(this);
    connect(&dialogUrl_, SIGNAL(doneUrl(QString,QString)),
            this, SLOT(addUrlToBookmarks(QString,QString)));
    
    dialogUrl_.exec();
}

void vulnerability::addUrlToBookmarks(const QString urlName, const QString urlAddr) 
{
    logHistory *history_ = new logHistory(_ui->treeWidgetVulnUrl, "nmapsi4/nameUrlVuln" , "nmapsi4/nameUrlAddr", -1);
    history_->addItemHistory(urlName, urlAddr);
    history_->updateBookMarks();
    delete history_;
    // reload comboVuln with website
    updateComboWebV();
}

void vulnerability::removeUrlToBookmarks() 
{
    if (_ui->treeWidgetVulnUrl->selectedItems().isEmpty()) 
    {
        return;
    }
    
    //remove url vuln
    logHistory *history_ = new logHistory(_ui->treeWidgetVulnUrl, "nmapsi4/nameUrlVuln" , "nmapsi4/nameUrlAddr", -1);
    history_->deleteItemBookmark(_ui->treeWidgetVulnUrl->selectedItems()[0]->text(0));
    delete history_;
    updateComboWebV();
}

void vulnerability::updateFontHostVuln() 
{
    _ui->comboVulnRis->clear();
    _collections.value("search-act")->setEnabled(true);
    _ui->comboVulnRis->setStyleSheet(QString::fromUtf8(""));
    bool signalState = _ui->comboVulnRis->lineEdit()->disconnect(SIGNAL(cursorPositionChanged(int,int)));
    
    if (!signalState)
        return;
    
    connect(_ui->comboVulnRis, SIGNAL(editTextChanged(QString)),
            this, SLOT(callSearchHistoryVuln()));
}

