/* * Copyright (C) 2004 Robert Hogan */ #include #include "kuarantine.h" #include "dbviewer.h" #include "klamav.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include Kuarantine::Kuarantine(QWidget *parent, const char *name) : QWidget(parent, name) { config = KGlobal::config(); config->setGroup("Kuarantine"); lastQuarLocations = config->readListEntry("KuarantineLocations"); //kdDebug() << "in quarantine " << endl; if (lastQuarLocations.isEmpty()){ createQuarDir(); }else{ for (QStringList::Iterator it = lastQuarLocations.begin(); it == lastQuarLocations.begin(); it++ ) quarloc = *it; if (!(KIO::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(QString("Items %1").arg(quarloc)); if (lastQuarItems.isEmpty()){ config->writeEntry(QString("Items %1").arg(quarloc), ""); lastQuarItems = config->readListEntry(QString("Items %1").arg(quarloc)); } //Get History for this location lastHistoryItems = config->readListEntry(QString("History %1").arg(quarloc)); if (lastHistoryItems.isEmpty()){ config->writeEntry(QString("History %1").arg(quarloc), ""); config->sync(); lastHistoryItems = config->readListEntry(QString("History %1").arg(quarloc)); } //Create GUI QVBoxLayout *vbox = new QVBoxLayout(this, KDialog::marginHint(), KDialog::spacingHint(), "vbox"); QGroupBox *group = new QGroupBox(i18n("Quarantine Location"), this); vbox->addWidget(group); QGridLayout *layout = new QGridLayout( group, 9, 3, KDialog::spacingHint(), KDialog::spacingHint(), "layout"); layout->addRowSpacing(0, group->fontMetrics().height()); layout->setColStretch(0, 1); layout->setColStretch(1, 1); QWidget *hlp = new QWidget( group ); layout->addMultiCellWidget(hlp, 1,1, 0,2); QHBoxLayout *dir_layout = new QHBoxLayout(hlp, KDialog::spacingHint() ); QLabel *dir_label = new QLabel(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, SIGNAL(urlSelected(const QString &)), SLOT(updateLastQuarLocations()) ); connect( dir_combo, SIGNAL(textChanged(const QString &)), SLOT(updateLastQuarLocations()) ); QGroupBox *group2 = new QGroupBox(i18n("Contents Of Quarantine"), this); vbox->addWidget(group2); QGridLayout *layout2 = new QGridLayout( group2, 9, 3, KDialog::spacingHint(), KDialog::spacingHint(), "layout2"); layout2->addRowSpacing(0, group2->fontMetrics().height()); layout2->setColStretch(0, 1); layout2->setColStretch(1, 1); QWidget *hlp2 = new QWidget( group2 ); layout2->addMultiCellWidget(hlp2, 1,1, 0,2); QHBoxLayout *dir_layout2 = new QHBoxLayout(hlp2, KDialog::spacingHint() ); // currentbox = new QListBox(hlp2); // QFontMetrics rb_fm(currentbox->fontMetrics()); // currentbox->setMinimumSize(rb_fm.width("0")*25, // rb_fm.lineSpacing()*8); // dir_layout2->addWidget(currentbox); currentbox = new QListView(hlp2); currentbox->setShowSortIndicator(true); QFontMetrics 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(QListView::AllColumns); currentbox->setSelectionMode( QListView::Extended ); currentbox->setAllColumnsShowFocus(true); qmenu = new QPopupMenu( currentbox ); connect(currentbox, SIGNAL( contextMenuRequested( QListViewItem *, const QPoint& , int ) ), this, SLOT( slotRMB( QListViewItem *, const QPoint &, int ) ) ); dir_layout2->addWidget(currentbox); //layout->addMultiCellWidget(currentbox); refresh(); KButtonBox *actionbox = new KButtonBox(hlp2, Qt::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, SIGNAL(clicked()), SLOT(refresh()) ); connect( search_button, SIGNAL(clicked()), SLOT(slotSearch()) ); connect( cancel_button, SIGNAL(clicked()), SLOT(slotCancel()) ); QGroupBox *group3 = new QGroupBox(i18n("Quarantine History"), this); vbox->addWidget(group3); QGridLayout *layout3 = new QGridLayout( group3, 9, 2, KDialog::spacingHint(), KDialog::spacingHint(), "layout3"); layout3->addRowSpacing(0, group3->fontMetrics().height()); layout3->setColStretch(0, 1); layout3->setColStretch(1, 1); QWidget *hlp3 = new QWidget( group3 ); layout3->addMultiCellWidget(hlp3, 1,1, 0,2); QHBoxLayout *dir_layout3 = new QHBoxLayout(hlp3, KDialog::spacingHint() ); // historybox = new QListBox(hlp3); // QFontMetrics rb_fm3(historybox->fontMetrics()); // historybox->setMinimumSize(rb_fm3.width("0")*25, // rb_fm3.lineSpacing()*8); // dir_layout3->addWidget(historybox); historybox = new QListView(hlp3); historybox->setShowSortIndicator(true); QFontMetrics 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(QListView::AllColumns); historybox->setSelectionMode( QListView::Extended ); historybox->setAllColumnsShowFocus(true); hmenu = new QPopupMenu( historybox ); connect(historybox, SIGNAL( contextMenuRequested( QListViewItem *, const QPoint& , int ) ), this, SLOT( slotRMB( QListViewItem *, const QPoint &, int ) ) ); dir_layout3->addWidget(historybox); //layout->addMultiCellWidget(historybox, 2, 2, 0, 2); KButtonBox *actionbox3 = new KButtonBox(hlp3, Qt::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, SIGNAL(clicked()), SLOT(slotClearHistory()) ); connect( cancel_button3, SIGNAL(clicked()), SLOT(slotDeleteHistory()) ); } Kuarantine::~Kuarantine() { } void Kuarantine::refresh() { QStringList obsoleteQuarItems; config = KGlobal::config(); config->setGroup("Kuarantine"); lastQuarItems = config->readListEntry(QString("Items %1").arg(quarloc)); if (!(KIO::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 (QStringList::Iterator it = lastQuarItems.begin(); it != lastQuarItems.end(); it++ ){ QString fname = getFileName(*it); QString itemname = getVirusName(*it); QString when = getWhen(*it); QStringList tokens = QStringList::split ( "/", fname, FALSE ); QString qname = tokens.last(); qname.prepend("/"); qname.prepend(quarloc); qname.append(":"+when); //kdDebug() << qname << endl; if (KIO::NetAccess::exists(qname,TRUE,NULL)){ //currentbox->insertItem(*it); new QListViewItem( currentbox, fname, itemname,when); }else{ //kdDebug() << qname << "doesna exist" << endl; obsoleteQuarItems.append(*it); } } for (QStringList::Iterator it = obsoleteQuarItems.begin(); it != obsoleteQuarItems.end(); it++ ) lastQuarItems.remove(*it); config->writeEntry(QString("Items %1").arg(quarloc), lastQuarItems); } config->sync(); } void Kuarantine::refreshhistory() { config = KGlobal::config(); config->setGroup("Kuarantine"); lastHistoryItems = config->readListEntry(QString("History %1").arg(quarloc)); historybox->clear(); for (QStringList::Iterator it = lastHistoryItems.begin(); it != lastHistoryItems.end(); it++ ){ QString fname = getFileName(*it); QString itemname = getVirusName(*it); QString when = getWhen(*it); new QListViewItem( historybox, fname, itemname,when); } } void Kuarantine::load() { QString 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 (QStringList::Iterator it = lastQuarItems.begin(); it != lastQuarItems.end(); it++ ){ QString fname = getFileName(*it); QString itemname = getVirusName(*it); QString when = getWhen(*it); new QListViewItem( currentbox, fname, itemname,when); } } void Kuarantine::slotSearch() { //if (!(currentbox->selectedItem())) // return; QPtrList list; QListViewItemIterator it( currentbox, QListViewItemIterator::Selected ); while ( it.current() ) { QListViewItem* tItem = it.current(); config = KGlobal::config(); config->setGroup("Kuarantine"); lastQuarItems = config->readListEntry(QString("Items %1").arg(quarloc)); lastHistoryItems = config->readListEntry(QString("History %1").arg(quarloc)); QString fname = tItem->text(0); QStringList tokens = QStringList::split ( "/", fname, FALSE ); QString qname = tokens.last(); qname.prepend("/"); qname.prepend(quarloc); qname.append(":"+tItem->text(2)); if (KIO::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(QString("Items %1").arg(quarloc), lastQuarItems); config->sync(); }else{ KMessageBox::information (this,i18n("

There was a problem restoring %1. 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.

").arg(fname)); } ++it; } for( QListViewItem *item = list.first(); item; item = list.next() ) { delete item; } } void Kuarantine::updateLastQuarLocations() { config = KGlobal::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; QPtrList list; QListViewItemIterator it( currentbox, QListViewItemIterator::Selected ); while ( it.current() ) { //QListViewItem* tItem = ( *it ); //if (tItem->isSelected()){ config = KGlobal::config(); config->setGroup("Kuarantine"); lastQuarItems = config->readListEntry(QString("Items %1").arg(quarloc)); lastHistoryItems = config->readListEntry(QString("History %1").arg(quarloc)); QString QuarLocation = dir_combo->url(); //QStringList tokens = QStringList::split ( ":", ( it.current() )->text(), FALSE ); QString fname = ( it.current() )->text(0); QString itemname = ( it.current() )->text(1); QString when = ( it.current() )->text(2); QStringList tokens = QStringList::split ( "/", fname, FALSE ); QString qname = tokens.last(); qname.prepend("/"); qname.prepend(QuarLocation); qname.append(":"+( it.current() )->text(2)); if (KIO::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 QListViewItem( 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( QListViewItem *item = list.first(); item; item = list.next() ) { delete item; } config->writeEntry(QString("Items %1").arg(quarloc), lastQuarItems); config->writeEntry(QString("History %1").arg(quarloc), lastHistoryItems); config->sync(); } void Kuarantine::slotClearHistory() { historybox->clear(); config = KGlobal::config(); config->setGroup("Kuarantine"); lastHistoryItems = config->readListEntry(QString("History %1").arg(quarloc)); if (lastHistoryItems.isEmpty()) return; lastHistoryItems.clear(); config->writeEntry(QString("History %1").arg(quarloc), lastHistoryItems); config->sync(); } void Kuarantine::slotDeleteHistory() { //if (!(historybox->selectedItem())) // return; //QListViewItem* tItem = historybox->selectedItem(); config->setGroup("Kuarantine"); lastHistoryItems = config->readListEntry(QString("History %1").arg(quarloc)); QPtrList list; QListViewItemIterator it( historybox, QListViewItemIterator::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( QListViewItem *item = list.first(); item; item = list.next() ) { delete item; } config->writeEntry(QString("History %1").arg(quarloc), lastHistoryItems); config->sync(); } void Kuarantine::setDirName(QString dir){ // dir_combo->setEditText(dir); dir_combo->setURL(dir); } void Kuarantine::createQuarDir(){ QString path = getenv("HOME"); bool ok = true; // directory exist? path += "/.klamav"; QDir klamavdir(path); if (!klamavdir.exists() && !klamavdir.mkdir(path)) ok = false; path += "/quarantine"; if (ok) { QDir klamavqdir(path); if (!klamavqdir.exists() && !klamavqdir.mkdir(path)) ok = false; else chmod((const char *)path,0700); } if (ok){ quarloc = QString("%1").arg(path); lastQuarLocations.append( QString("%1").arg(path)); config = KGlobal::config(); config->setGroup("Kuarantine"); config->writeEntry("KuarantineLocations", lastQuarLocations); config->sync(); lastQuarLocations = config->readListEntry("KuarantineLocations"); } KMessageBox::information (this,QString(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)); } QString Kuarantine::getFileName(QString entry){ int fnameStartPoint = 0; int dtStartPoint = entry.findRev(":"); int fnameEndPoint = entry.findRev(":", (signed int)-((entry.length() - dtStartPoint)+1)); QString fname = entry.mid(fnameStartPoint,(fnameEndPoint - fnameStartPoint)); //kdDebug() << fname << endl; return fname; } QString Kuarantine::getVirusName(QString entry){ int dtStartPoint = entry.findRev(":"); int fnameEndPoint = entry.findRev(":", (signed int)-((entry.length() - dtStartPoint)+1)); QString itemName = entry.mid((fnameEndPoint+1),((dtStartPoint+1) - (fnameEndPoint+2))); //kdDebug() << itemName << endl; return itemName.stripWhiteSpace(); } QString Kuarantine::getWhen(QString entry){ int dtStartPoint = entry.findRev(":"); QString when = entry.mid((dtStartPoint+1),(entry.length() - (dtStartPoint+1))); //kdDebug() << when << endl; return when; } void Kuarantine::slotRMB( QListViewItem* Item, const QPoint & point, int ) { if( Item ){ QPixmap gicon; QPixmap vicon; QPixmap ticon; QPixmap vlicon; QString iconPath = locate("cache", KMimeType::favIconForURL("http://www.viruspool.net")+".png"); if ( iconPath.isEmpty() ) vicon = SmallIcon("find"); else vicon = QPixmap( iconPath ); iconPath = locate("cache", KMimeType::favIconForURL("http://www.google.com")+".png"); if ( iconPath.isEmpty() ) gicon = SmallIcon("find"); else gicon = QPixmap( iconPath ); iconPath = locate("cache", KMimeType::favIconForURL("http://www.trendmicro.com")+".png"); if ( iconPath.isEmpty() ) ticon = SmallIcon("find"); else ticon = QPixmap( iconPath ); iconPath = locate("cache", KMimeType::favIconForURL("http://www.viruslist.com")+".png"); if ( iconPath.isEmpty() ) vlicon = SmallIcon("find"); else vlicon = QPixmap( iconPath ); if (Item->listView() == currentbox){ qmenu->clear(); qmenu->insertItem( vlicon,i18n("Search for %1 with VirusList").arg(Item->text(1)), this, SLOT(slotVirusListCurrent()) ); qmenu->insertItem( vicon,i18n("Search for %1 with VirusPool").arg(Item->text(1)), this, SLOT(slotVirusPoolCurrent()) ); qmenu->insertItem( ticon,i18n("Search for %1 with Trend Micro").arg(Item->text(1)), this, SLOT(slotTrendMicroCurrent()) ); qmenu->insertItem( gicon,i18n("Search for %1 with Google").arg(Item->text(1)), this, SLOT(slotGoogleCurrent()) ); qmenu->popup( point ); }else if (Item->listView() == historybox){ hmenu->clear(); hmenu->insertItem( vicon,i18n("Search for %1 with VirusPool").arg(Item->text(1)), this, SLOT(slotVirusPoolHistory()) ); hmenu->insertItem( vicon,i18n("Search for %1 with VirusList").arg(Item->text(1)), this, SLOT(slotVirusListHistory()) ); hmenu->insertItem( ticon,i18n("Search for %1 with Trend Micro").arg(Item->text(1)), this, SLOT(slotTrendMicroHistory()) ); hmenu->insertItem( gicon,i18n("Search for %1 with Google").arg(Item->text(1)), this, SLOT(slotGoogleHistory()) ); hmenu->popup( point ); } } } void Kuarantine::slotVirusPoolCurrent() { QString name = currentbox->currentItem()->text(1); kmain->klamdb->slotExternal(name,"VirusPool"); } void Kuarantine::slotVirusListCurrent() { QString name = currentbox->currentItem()->text(1); kmain->klamdb->slotExternal(name,"VirusList"); } void Kuarantine::slotGoogleCurrent() { QString name = currentbox->currentItem()->text(1); kmain->klamdb->slotExternal(name,"Google"); } void Kuarantine::slotTrendMicroCurrent() { QString name = currentbox->currentItem()->text(1); kmain->klamdb->slotExternal(name, "TrendMicro"); } void Kuarantine::slotVirusPoolHistory() { QString name = historybox->currentItem()->text(1); kmain->klamdb->slotExternal(name,"VirusPool"); } void Kuarantine::slotVirusListHistory() { QString name = historybox->currentItem()->text(1); kmain->klamdb->slotExternal(name,"VirusList"); } void Kuarantine::slotGoogleHistory() { QString name = historybox->currentItem()->text(1); kmain->klamdb->slotExternal(name,"Google"); } void Kuarantine::slotTrendMicroHistory() { QString name = historybox->currentItem()->text(1); kmain->klamdb->slotExternal(name, "TrendMicro"); } #include "kuarantine.moc"