You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
klamav/src/kuarantine.cpp

679 lines
22 KiB

/*
* Copyright (C) 2004 Robert Hogan <robert at roberthogan dot net>
*/
#include <config.h>
#include "kuarantine.h"
#include "dbviewer.h"
#include "klamav.h"
#include <tdelocale.h>
#include <kiconloader.h>
#include <tdemenubar.h>
#include <kstatusbar.h>
#include <kkeydialog.h>
#include <tdeio/netaccess.h>
#include <tdefiledialog.h>
#include <kbuttonbox.h>
#include <kurlrequester.h>
#include <kurlcompletion.h>
#include <kcombobox.h>
#include <tqlayout.h>
#include <tdemessagebox.h>
#include <kstandarddirs.h>
Kuarantine::Kuarantine(TQWidget *parent, const char *name)
: TQWidget(parent, name)
{
config = TDEGlobal::config();
config->setGroup("Kuarantine");
lastQuarLocations = config->readListEntry("KuarantineLocations");
//kdDebug() << "in quarantine " << endl;
if (lastQuarLocations.isEmpty()){
createQuarDir();
}else{
for (TQStringList::Iterator it = lastQuarLocations.begin(); it == lastQuarLocations.begin(); it++ )
quarloc = *it;
if (!(TDEIO::NetAccess::exists(quarloc,TRUE,NULL))){
KMessageBox::information (this,i18n( "Your current quarantine location ('%1') no longer exists. I'm going to attempt to create a new one.").arg(quarloc));
createQuarDir();
}
}
//Get Items for this location
lastQuarItems = config->readListEntry(TQString("Items %1").arg(quarloc));
if (lastQuarItems.isEmpty()){
config->writeEntry(TQString("Items %1").arg(quarloc), "");
lastQuarItems = config->readListEntry(TQString("Items %1").arg(quarloc));
}
//Get History for this location
lastHistoryItems = config->readListEntry(TQString("History %1").arg(quarloc));
if (lastHistoryItems.isEmpty()){
config->writeEntry(TQString("History %1").arg(quarloc), "");
config->sync();
lastHistoryItems = config->readListEntry(TQString("History %1").arg(quarloc));
}
//Create GUI
TQVBoxLayout *vbox = new TQVBoxLayout(this, KDialog::marginHint(),
KDialog::spacingHint(), "vbox");
TQGroupBox *group = new TQGroupBox(i18n("Quarantine Location"), this);
vbox->addWidget(group);
TQGridLayout *layout = new TQGridLayout( group, 9, 3, KDialog::spacingHint(),
KDialog::spacingHint(), "layout");
layout->addRowSpacing(0, group->fontMetrics().height());
layout->setColStretch(0, 1);
layout->setColStretch(1, 1);
TQWidget *hlp = new TQWidget( group );
layout->addMultiCellWidget(hlp, 1,1, 0,2);
TQHBoxLayout *dir_layout = new TQHBoxLayout(hlp, KDialog::spacingHint() );
TQLabel *dir_label = new TQLabel(i18n("&Directory:"), hlp);
dir_label->setFixedSize(dir_label->sizeHint());
dir_label->adjustSize();
dir_layout->addWidget(dir_label);
// anders: KDE is an amazing tool:)
dir_combo = new KURLRequester( new KComboBox(true, hlp), hlp, "dir combo" );
dir_combo->completionObject()->setMode(KURLCompletion::DirCompletion);
dir_combo->comboBox()->insertStringList(lastQuarLocations);
dir_combo->setMode( KFile::Directory|KFile::LocalOnly );
dir_layout->addWidget(dir_combo);
dir_label->setBuddy(dir_combo);
connect( dir_combo, TQ_SIGNAL(urlSelected(const TQString &)),
TQ_SLOT(updateLastQuarLocations()) );
connect( dir_combo, TQ_SIGNAL(textChanged(const TQString &)),
TQ_SLOT(updateLastQuarLocations()) );
TQGroupBox *group2 = new TQGroupBox(i18n("Contents Of Quarantine"), this);
vbox->addWidget(group2);
TQGridLayout *layout2 = new TQGridLayout( group2, 9, 3, KDialog::spacingHint(),
KDialog::spacingHint(), "layout2");
layout2->addRowSpacing(0, group2->fontMetrics().height());
layout2->setColStretch(0, 1);
layout2->setColStretch(1, 1);
TQWidget *hlp2 = new TQWidget( group2 );
layout2->addMultiCellWidget(hlp2, 1,1, 0,2);
TQHBoxLayout *dir_layout2 = new TQHBoxLayout(hlp2, KDialog::spacingHint() );
// currentbox = new TQListBox(hlp2);
// TQFontMetrics rb_fm(currentbox->fontMetrics());
// currentbox->setMinimumSize(rb_fm.width("0")*25,
// rb_fm.lineSpacing()*8);
// dir_layout2->addWidget(currentbox);
currentbox = new TQListView(hlp2);
currentbox->setShowSortIndicator(true);
TQFontMetrics rb_fm(currentbox->fontMetrics());
//currentbox->setMinimumSize(rb_fm.width("0")*55,
// rb_fm.lineSpacing()*15);
//kdDebug() << ((currentbox->width())/3) << endl;
currentbox->addColumn( i18n( "Name of File" ),0);
currentbox->addColumn( i18n( "Name of Virus Found" ),0);
currentbox->addColumn( i18n( "Date Quarantined" ),0);
currentbox->setResizeMode(TQListView::AllColumns);
currentbox->setSelectionMode( TQListView::Extended );
currentbox->setAllColumnsShowFocus(true);
qmenu = new TQPopupMenu( currentbox );
connect(currentbox, TQ_SIGNAL( contextMenuRequested( TQListViewItem *, const TQPoint& , int ) ),
this, TQ_SLOT( slotRMB( TQListViewItem *, const TQPoint &, int ) ) );
dir_layout2->addWidget(currentbox);
//layout->addMultiCellWidget(currentbox);
refresh();
KButtonBox *actionbox = new KButtonBox(hlp2, TQt::Vertical);
actionbox->addStretch();
refresh_button = actionbox->addButton(i18n("&Refresh"));
refresh_button->setDefault(true);
search_button = actionbox->addButton(i18n("&Restore"));
search_button->setDefault(true);
cancel_button = actionbox->addButton(i18n("&Delete"));
actionbox->addStretch();
actionbox->adjustSize();
actionbox->layout();
dir_layout2->addWidget(actionbox);
connect( refresh_button, TQ_SIGNAL(clicked()),
TQ_SLOT(refresh()) );
connect( search_button, TQ_SIGNAL(clicked()),
TQ_SLOT(slotSearch()) );
connect( cancel_button, TQ_SIGNAL(clicked()),
TQ_SLOT(slotCancel()) );
TQGroupBox *group3 = new TQGroupBox(i18n("Quarantine History"), this);
vbox->addWidget(group3);
TQGridLayout *layout3 = new TQGridLayout( group3, 9, 2, KDialog::spacingHint(),
KDialog::spacingHint(), "layout3");
layout3->addRowSpacing(0, group3->fontMetrics().height());
layout3->setColStretch(0, 1);
layout3->setColStretch(1, 1);
TQWidget *hlp3 = new TQWidget( group3 );
layout3->addMultiCellWidget(hlp3, 1,1, 0,2);
TQHBoxLayout *dir_layout3 = new TQHBoxLayout(hlp3, KDialog::spacingHint() );
// historybox = new TQListBox(hlp3);
// TQFontMetrics rb_fm3(historybox->fontMetrics());
// historybox->setMinimumSize(rb_fm3.width("0")*25,
// rb_fm3.lineSpacing()*8);
// dir_layout3->addWidget(historybox);
historybox = new TQListView(hlp3);
historybox->setShowSortIndicator(true);
TQFontMetrics rb_fm2(historybox->fontMetrics());
//historybox->setMinimumSize(rb_fm2.width("0")*55,
// rb_fm2.lineSpacing()*15);
historybox->addColumn( i18n( "Name of File" ),(historybox->width()));
historybox->addColumn( i18n( "Name of Virus Found" ),(historybox->width()));
historybox->addColumn( i18n( "Date Quarantined" ),(historybox->width()));
historybox->setResizeMode(TQListView::AllColumns);
historybox->setSelectionMode( TQListView::Extended );
historybox->setAllColumnsShowFocus(true);
hmenu = new TQPopupMenu( historybox );
connect(historybox, TQ_SIGNAL( contextMenuRequested( TQListViewItem *, const TQPoint& , int ) ),
this, TQ_SLOT( slotRMB( TQListViewItem *, const TQPoint &, int ) ) );
dir_layout3->addWidget(historybox);
//layout->addMultiCellWidget(historybox, 2, 2, 0, 2);
KButtonBox *actionbox3 = new KButtonBox(hlp3, TQt::Vertical);
actionbox3->addStretch();
search_button3 = actionbox3->addButton(i18n("&Clear All"));
search_button3->setDefault(true);
cancel_button3 = actionbox3->addButton(i18n("&Delete"));
cancel_button3->setEnabled(true);
actionbox3->addStretch();
actionbox3->layout();
dir_layout3->addWidget(actionbox3);
refreshhistory();
connect( search_button3, TQ_SIGNAL(clicked()),
TQ_SLOT(slotClearHistory()) );
connect( cancel_button3, TQ_SIGNAL(clicked()),
TQ_SLOT(slotDeleteHistory()) );
}
Kuarantine::~Kuarantine()
{
}
void Kuarantine::refresh()
{
TQStringList obsoleteQuarItems;
config = TDEGlobal::config();
config->setGroup("Kuarantine");
lastQuarItems = config->readListEntry(TQString("Items %1").arg(quarloc));
if (!(TDEIO::NetAccess::exists(quarloc,TRUE,NULL))){
KMessageBox::information (this,i18n("Your current quarantine location ('%1') no longer exists. I'm going to attempt to create a new one.").arg(quarloc));
createQuarDir();
}else{
currentbox->clear();
for (TQStringList::Iterator it = lastQuarItems.begin(); it != lastQuarItems.end(); it++ ){
TQString fname = getFileName(*it);
TQString itemname = getVirusName(*it);
TQString when = getWhen(*it);
TQStringList tokens = TQStringList::split ( "/", fname, FALSE );
TQString qname = tokens.last();
qname.prepend("/");
qname.prepend(quarloc);
qname.append(":"+when);
//kdDebug() << qname << endl;
if (TDEIO::NetAccess::exists(qname,TRUE,NULL)){
//currentbox->insertItem(*it);
new TQListViewItem( currentbox, fname, itemname,when);
}else{
//kdDebug() << qname << "doesna exist" << endl;
obsoleteQuarItems.append(*it);
}
}
for (TQStringList::Iterator it = obsoleteQuarItems.begin(); it != obsoleteQuarItems.end(); it++ )
lastQuarItems.remove(*it);
config->writeEntry(TQString("Items %1").arg(quarloc), lastQuarItems);
}
config->sync();
}
void Kuarantine::refreshhistory()
{
config = TDEGlobal::config();
config->setGroup("Kuarantine");
lastHistoryItems = config->readListEntry(TQString("History %1").arg(quarloc));
historybox->clear();
for (TQStringList::Iterator it = lastHistoryItems.begin(); it != lastHistoryItems.end(); it++ ){
TQString fname = getFileName(*it);
TQString itemname = getVirusName(*it);
TQString when = getWhen(*it);
new TQListViewItem( historybox, fname, itemname,when);
}
}
void Kuarantine::load()
{
TQString target;
// the below code is what you should normally do. in this
// example case, we want the url to our own. you probably
// want to use this code instead for your app
currentbox->clear();
for (TQStringList::Iterator it = lastQuarItems.begin(); it != lastQuarItems.end(); it++ ){
TQString fname = getFileName(*it);
TQString itemname = getVirusName(*it);
TQString when = getWhen(*it);
new TQListViewItem( currentbox, fname, itemname,when);
}
}
void Kuarantine::slotSearch()
{
//if (!(currentbox->selectedItem()))
// return;
TQPtrList<TQListViewItem> list;
TQListViewItemIterator it( currentbox, TQListViewItemIterator::Selected );
while ( it.current() ) {
TQListViewItem* tItem = it.current();
config = TDEGlobal::config();
config->setGroup("Kuarantine");
lastQuarItems = config->readListEntry(TQString("Items %1").arg(quarloc));
lastHistoryItems = config->readListEntry(TQString("History %1").arg(quarloc));
TQString fname = tItem->text(0);
TQStringList tokens = TQStringList::split ( "/", fname, FALSE );
TQString qname = tokens.last();
qname.prepend("/");
qname.prepend(quarloc);
qname.append(":"+tItem->text(2));
if (TDEIO::NetAccess::file_move(qname,fname)){
lastQuarItems.remove(tItem->text(0)+":"+tItem->text(1)+":"+tItem->text(2));
//currentbox->takeItem(currentbox->currentItem());
list.prepend( it.current() );
config->writeEntry(TQString("Items %1").arg(quarloc), lastQuarItems);
config->sync();
}else{
KMessageBox::information (this,i18n("<p>There was a problem restoring <b>%1</b>. Check your diskspace, the permissions on the location you are restoring to, and whether a file with the same name already exists in that location. </p>").arg(fname));
}
++it;
}
for( TQListViewItem *item = list.first(); item; item = list.next() )
{
delete item;
}
}
void Kuarantine::updateLastQuarLocations()
{
config = TDEGlobal::config();
config->setGroup("Kuarantine");
lastQuarLocations = config->readListEntry("KuarantineLocations");
if (lastQuarLocations.contains(dir_combo->url()) == 0) {
dir_combo->comboBox()->insertItem(dir_combo->url(), 0);
lastQuarLocations.prepend(dir_combo->url());
if (lastQuarLocations.count() > 10) {
lastQuarLocations.remove(lastQuarLocations.fromLast());
dir_combo->comboBox()->removeItem(dir_combo->comboBox()->count() - 1);
}
}else{
lastQuarLocations.remove(dir_combo->url());
lastQuarLocations.prepend(dir_combo->url());
}
config->writeEntry("KuarantineLocations", lastQuarLocations);
config->sync();
quarloc = dir_combo->url();
refresh();
refreshhistory();
}
void Kuarantine::slotCancel()
{
//if (!(currentbox->selectedItem()))
// return;
TQPtrList<TQListViewItem> list;
TQListViewItemIterator it( currentbox, TQListViewItemIterator::Selected );
while ( it.current() ) {
//TQListViewItem* tItem = ( *it );
//if (tItem->isSelected()){
config = TDEGlobal::config();
config->setGroup("Kuarantine");
lastQuarItems = config->readListEntry(TQString("Items %1").arg(quarloc));
lastHistoryItems = config->readListEntry(TQString("History %1").arg(quarloc));
TQString QuarLocation = dir_combo->url();
//TQStringList tokens = TQStringList::split ( ":", ( it.current() )->text(), FALSE );
TQString fname = ( it.current() )->text(0);
TQString itemname = ( it.current() )->text(1);
TQString when = ( it.current() )->text(2);
TQStringList tokens = TQStringList::split ( "/", fname, FALSE );
TQString qname = tokens.last();
qname.prepend("/");
qname.prepend(QuarLocation);
qname.append(":"+( it.current() )->text(2));
if (TDEIO::NetAccess::del(qname,NULL)){
lastQuarItems.remove(( it.current() )->text(0)+":"+( it.current() )->text(1)+":"+( it.current() )->text(2));
lastHistoryItems.prepend(( it.current() )->text(0)+":"+( it.current() )->text(1)+":"+( it.current() )->text(2));
new TQListViewItem( historybox, fname, itemname,when);
//historybox->inser( it.current() )(( it.current() )->text());
//currentbox->takeItem(( it.current() ));
list.prepend( it.current() );
}else{
KMessageBox::information (this,i18n( "There was a problem deleting the file. Is there a problem with the permissions on the quarantine folder? " ));
}
//}
++it;
}
for( TQListViewItem *item = list.first(); item; item = list.next() )
{
delete item;
}
config->writeEntry(TQString("Items %1").arg(quarloc), lastQuarItems);
config->writeEntry(TQString("History %1").arg(quarloc), lastHistoryItems);
config->sync();
}
void Kuarantine::slotClearHistory()
{
historybox->clear();
config = TDEGlobal::config();
config->setGroup("Kuarantine");
lastHistoryItems = config->readListEntry(TQString("History %1").arg(quarloc));
if (lastHistoryItems.isEmpty())
return;
lastHistoryItems.clear();
config->writeEntry(TQString("History %1").arg(quarloc), lastHistoryItems);
config->sync();
}
void Kuarantine::slotDeleteHistory()
{
//if (!(historybox->selectedItem()))
// return;
//TQListViewItem* tItem = historybox->selectedItem();
config->setGroup("Kuarantine");
lastHistoryItems = config->readListEntry(TQString("History %1").arg(quarloc));
TQPtrList<TQListViewItem> list;
TQListViewItemIterator it( historybox, TQListViewItemIterator::Selected );
while ( it.current() ) {
lastHistoryItems.remove(( it.current() )->text(0)+":"+( it.current() )->text(1)+":"+( it.current() )->text(2));
//historybox->takeItem(historybox->curren( it.current() )());
list.prepend( it.current() );
++it;
}
for( TQListViewItem *item = list.first(); item; item = list.next() )
{
delete item;
}
config->writeEntry(TQString("History %1").arg(quarloc), lastHistoryItems);
config->sync();
}
void Kuarantine::setDirName(TQString dir){
// dir_combo->setEditText(dir);
dir_combo->setURL(dir);
}
void Kuarantine::createQuarDir(){
TQString path = getenv("HOME");
bool ok = true;
// directory exist?
path += "/.klamav";
TQDir klamavdir(path);
if (!klamavdir.exists() && !klamavdir.mkdir(path))
ok = false;
path += "/quarantine";
if (ok)
{
TQDir klamavqdir(path);
if (!klamavqdir.exists() && !klamavqdir.mkdir(path))
ok = false;
else
chmod(path.ascii(),0700);
}
if (ok){
quarloc = TQString("%1").arg(path);
lastQuarLocations.append( TQString("%1").arg(path));
config = TDEGlobal::config();
config->setGroup("Kuarantine");
config->writeEntry("KuarantineLocations", lastQuarLocations);
config->sync();
lastQuarLocations = config->readListEntry("KuarantineLocations");
}
KMessageBox::information (this,TQString(ok ? i18n( "Your default quarantine location has been set up as '%1'. You can change this to something else if you want to." ) : i18n( "I cannot create the directory '%1' for you. Something is wrong with your HOME or klamav directory. You have to adjust your quarantine directory by your self." )).arg(path));
}
TQString Kuarantine::getFileName(TQString entry){
int fnameStartPoint = 0;
int dtStartPoint = entry.findRev(":");
int fnameEndPoint = entry.findRev(":", (signed int)-((entry.length() - dtStartPoint)+1));
TQString fname = entry.mid(fnameStartPoint,(fnameEndPoint - fnameStartPoint));
//kdDebug() << fname << endl;
return fname;
}
TQString Kuarantine::getVirusName(TQString entry){
int dtStartPoint = entry.findRev(":");
int fnameEndPoint = entry.findRev(":", (signed int)-((entry.length() - dtStartPoint)+1));
TQString itemName = entry.mid((fnameEndPoint+1),((dtStartPoint+1) - (fnameEndPoint+2)));
//kdDebug() << itemName << endl;
return itemName.stripWhiteSpace();
}
TQString Kuarantine::getWhen(TQString entry){
int dtStartPoint = entry.findRev(":");
TQString when = entry.mid((dtStartPoint+1),(entry.length() - (dtStartPoint+1)));
//kdDebug() << when << endl;
return when;
}
void Kuarantine::slotRMB( TQListViewItem* Item, const TQPoint & point, int )
{
if( Item ){
TQPixmap gicon;
TQPixmap vicon;
TQPixmap ticon;
TQPixmap vlicon;
TQString iconPath = locate("cache", KMimeType::favIconForURL("http://www.viruspool.net")+".png");
if ( iconPath.isEmpty() )
vicon = SmallIcon("edit-find");
else
vicon = TQPixmap( iconPath );
iconPath = locate("cache", KMimeType::favIconForURL("http://www.google.com")+".png");
if ( iconPath.isEmpty() )
gicon = SmallIcon("edit-find");
else
gicon = TQPixmap( iconPath );
iconPath = locate("cache", KMimeType::favIconForURL("http://www.trendmicro.com")+".png");
if ( iconPath.isEmpty() )
ticon = SmallIcon("edit-find");
else
ticon = TQPixmap( iconPath );
iconPath = locate("cache", KMimeType::favIconForURL("http://www.viruslist.com")+".png");
if ( iconPath.isEmpty() )
vlicon = SmallIcon("edit-find");
else
vlicon = TQPixmap( iconPath );
if (Item->listView() == currentbox){
qmenu->clear();
qmenu->insertItem( ticon,i18n("Search for %1 with Trend Micro").arg(Item->text(1)), this, TQ_SLOT(slotTrendMicroCurrent()) );
qmenu->insertItem( gicon,i18n("Search for %1 with Google").arg(Item->text(1)), this, TQ_SLOT(slotGoogleCurrent()) );
qmenu->popup( point );
}else if (Item->listView() == historybox){
hmenu->clear();
hmenu->insertItem( ticon,i18n("Search for %1 with Trend Micro").arg(Item->text(1)), this, TQ_SLOT(slotTrendMicroHistory()) );
hmenu->insertItem( gicon,i18n("Search for %1 with Google").arg(Item->text(1)), this, TQ_SLOT(slotGoogleHistory()) );
hmenu->popup( point );
}
}
}
void Kuarantine::slotGoogleCurrent()
{
TQString name = currentbox->currentItem()->text(1);
tdemain->klamdb->slotExternal(name,"Google");
}
void Kuarantine::slotTrendMicroCurrent()
{
TQString name = currentbox->currentItem()->text(1);
tdemain->klamdb->slotExternal(name, "TrendMicro");
}
void Kuarantine::slotGoogleHistory()
{
TQString name = historybox->currentItem()->text(1);
tdemain->klamdb->slotExternal(name,"Google");
}
void Kuarantine::slotTrendMicroHistory()
{
TQString name = historybox->currentItem()->text(1);
tdemain->klamdb->slotExternal(name, "TrendMicro");
}
#include "kuarantine.moc"