Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*
- * =====================================================================================
- * Filename: qgui.cpp
- * Description: Contains all the functions required by the GUI to connect to the
- * KDB server, update the database, inspect files, change settings.
- *
- * Version: 1.0
- * Created: 23/04/12 15:42:19
- * Compiler: "make" from QScanner root. Requires qt make installed
- * $ sudo apt-get install libqt4-dev
- *
- * Author: Oliver Fletcher, ttolf@lboro.ac.uk
- * University: Loughborough University
- * =====================================================================================
- */
- #include <iostream>
- #include <stdio.h>
- #include <QtGui>
- #include "qgui.h"
- #include "k.h"
- using namespace std;
- /*
- * === FUNCTION ======================================================================
- * Name: qguiApp
- * Description: GUI constructor function. Connects buttons to relevant functions and
- * sets up thread watchers.
- * =====================================================================================
- */
- qguiApp::qguiApp(QWidget *parent)
- {
- setupUi(this);
- scanning->setText(""); /* Scan in progress label set as blank */
- watcher = new QFutureWatcher<void>; /* Create thread watchers and futures */
- future = new QFuture<QByteArray>;
- updateWatcher = new QFutureWatcher<void>;
- updateFuture = new QFuture<QByteArray>;
- fileWatcher = new QFutureWatcher<void>;
- fileFuture = new QFuture<QByteArray>;
- // Crete connections for file browser button, file input box and drop down menu
- connect (pushButton_browse,SIGNAL( clicked() ),this,SLOT( getPathOrDir()));
- connect (scanType,SIGNAL( currentIndexChanged(int) ),this,SLOT( scanTypeChanged() ));
- connect (fileBrowse,SIGNAL( clicked() ),this,SLOT( getPath()));
- // Connects the scan button to run thread. Runs a function when it starts and finishes
- connect (scanButton,SIGNAL( clicked() ),this,SLOT( run_thread() ));
- connect (watcher,SIGNAL(started()),this,SLOT(scan()));
- connect (watcher,SIGNAL(finished()),this,SLOT(display_logs()));
- connect (updateButton,SIGNAL( clicked() ),this,SLOT( update_thread() ) );
- connect (updateWatcher,SIGNAL(started()),this,SLOT(update_start()));
- connect (updateWatcher,SIGNAL(finished()),this,SLOT(update_logs()));
- connect (fileinfoButton,SIGNAL( clicked() ),this,SLOT( file_thread() ) );
- connect (fileWatcher,SIGNAL(finished()),this,SLOT(file_logs()));
- // Clear consoles
- connect (clearScanButton,SIGNAL( clicked() ),this,SLOT( clearScan() ) );
- connect (clearFileButton,SIGNAL( clicked() ),this,SLOT( clearFile() ) );
- // Update Q server with settings
- connect (updateSettingsButton,SIGNAL( clicked() ),this,SLOT( updateSettings() ) );
- // Load settings
- connect (tabWidget,SIGNAL ( currentChanged(int) ),this,SLOT( loadSettings()));
- // Show the "Save" button when settings change
- connect (settingsMd5,SIGNAL ( clicked()),this,SLOT( showSave()));
- connect (settingsVirus,SIGNAL ( clicked()),this,SLOT( showSave()));
- connect (settingsVerbose,SIGNAL ( clicked()),this,SLOT( showSave()));
- connect (settingsUpdates,SIGNAL ( clicked() ),this,SLOT( showSave()));
- // Show help manual
- connect (help,SIGNAL( clicked() ),this,SLOT (showHelp()) );
- }
- /*
- * === FUNCTION ======================================================================
- * Name: update_thread()
- * Description: Run the functions update_query() in a separate thread. Set up a
- * watcher.
- * =====================================================================================
- */
- void qguiApp::update_thread()
- {
- *updateFuture = QtConcurrent::run( update_query );
- updateWatcher->setFuture(*updateFuture);
- }
- /*
- * === FUNCTION ======================================================================
- * Name: update_query()
- * Description: Checks for a valid connection to clamAV server. Connects to KDB
- * instance and sends the function "qupdate[]" which returns information
- * on the update.
- * Returns: logs -> Contains signatures updated and time
- * =====================================================================================
- */
- QByteArray update_query()
- {
- QByteArray logs;
- K result,line;
- unsigned char * str;
- const char * str1;
- if ( system("ping -c1 -s1 db.local.clamav.net > /dev/null" )){ /* Test internet connection */
- logs = "Error: No Internet Connection";
- return logs;
- }
- qconn *conn = new qconn; /* Create KDB connection */
- if(conn->isConnected()){
- result = conn->sync_query("qupdate[]");
- delete conn;
- }
- else {
- delete conn;
- logs = "Error connecting to database";
- return logs;
- }
- for(int i=0;i<result->n;i++) /* Loop through query results */
- {
- line=kK(result)[i]; /* Get first element */
- int s = line->n; /* Get char array size */
- str = (kC(line)); /* Assign to unsigned char */
- str[s] = '\0'; /* End string */
- str1 = reinterpret_cast<const char*>(str);
- logs.append(str1); /* Add to QByteArray logs */
- logs.append('\n');
- }
- return logs;
- }
- /*
- * === FUNCTION ======================================================================
- * Name: update_start
- * Description: Called when the update thread begins. Sets a label and shows a gif.
- * =====================================================================================
- */
- void qguiApp::update_start()
- {
- scanning->setText("Updating...");
- QMovie *movie = new QMovie("img/loading.gif");
- gif_loader->setMovie(movie);
- movie->start();
- }
- /*
- * === FUNCTION ======================================================================
- * Name: update_logs
- * Description: Called when the update thread is finished.
- * Receives the logs from the future object.
- * Clears the scanning gif and label.
- * Shows the log in the console.
- * =====================================================================================
- */
- void qguiApp::update_logs()
- {
- QByteArray ulogs = updateFuture->result(); /* Gets the return variable from update_query */
- scanConsole->setText(ulogs);
- scanning->setText("");
- gif_loader->clear();
- }
- /*
- * === FUNCTION ======================================================================
- * Name: run_thread
- * Description: Grabs the file or directory path selected.
- * Builds a Q query based on file/directory selected
- * Launches a thread to scan the file/directory
- * =====================================================================================
- */
- void qguiApp::run_thread()
- {
- string path;
- char * qinput;
- if(file->toPlainText().toStdString() == ""){ /* Check if a file has been selected */
- scanConsole->setText("Select file or Directory");
- return;
- }
- if(scanType->currentText() == "File"){ /* Convert path to directory and path */
- path=(file->toPlainText()).toStdString();
- fname=path.substr(path.find_last_of("/") + 1);
- dir=path.substr(0,path.find_last_of("/"));
- }
- else { /* Convert path to directory */
- path=(file->toPlainText()).toStdString();
- fname="";
- dir=path;
- }
- // Build the query to be sent to Q
- string input = "qscan[\"" + fname + "\";\"" + dir + "\"]";
- qinput = new char[input.size() + 1];
- copy(input.begin(),input.end(),qinput);
- qinput[input.size()] = '\0';
- if(fname==""){isdir=true;}else {isdir=false;} /* isdir -> is directory? */
- updateButton->setEnabled(false); /* Disable updates while scanning */
- *future = QtConcurrent::run( q_query, qinput, isdir ); /* Launch scan thread */
- watcher->setFuture(*future);
- }
- /*
- * === FUNCTION ======================================================================
- * Name: scan
- * Description: Launched when the scan begins. Alerts the user that a scan is in
- * progress and shows a loading animated gif.
- * =====================================================================================
- */
- void qguiApp::scan()
- {
- string scanInProgress,directory;
- if(isdir){ /* Build scan in progress string */
- scanInProgress = "Directory: ";
- }
- else {
- scanInProgress = "File: ";
- }
- scanInProgress = "Scanning " + scanInProgress;
- scanning->setText( scanInProgress.c_str() ); /* Set scan in progress label */
- directory = dir+fname; /* Build and set directory been scanned */
- filename->setText( directory.c_str() );
- QMovie *movie = new QMovie( "img/loading.gif" ); /* Show the loading gif */
- gif_loader->setMovie(movie);
- movie->start();
- }
- /*
- * === FUNCTION ======================================================================
- * Name: display_logs
- * Description: Gets the run_thread result for the scan query when its completed
- * Displays the result in the console window
- * =====================================================================================
- */
- void qguiApp::display_logs()
- {
- QByteArray slogs = future->result(); /* Get the QScan results */
- string logs = slogs.data(); /* Convert to string */
- // Inspect if malware was found or an error occurred
- bool found=logs.find("Malware Detected: ")!=string::npos;
- bool error=logs.find("Error connecting to database")!=string::npos;
- scanConsole->setText(slogs); /* Output results to console */
- if(!error){ /* Append virus warning */
- if(!found){
- scanConsole->append("**************************************************************\n\n NO VIRUSES FOUND \n\n**************************************************************\n\n");
- }
- else {
- scanConsole->append("**************************************************************\n\n VIRUSES FOUND (CHECK LOG ABOVE FOR DETAILS) \n\n**************************************************************\n\n");
- }
- }
- // Scroll the console to the bottom of the page
- QScrollBar *vScrollBar = scanConsole->verticalScrollBar();
- vScrollBar->triggerAction(QScrollBar::SliderToMaximum);
- updateButton->setEnabled(true); /* Clear the display */
- scanning->setText("");
- filename->setText("");
- gif_loader->clear();
- }
- /*
- * === FUNCTION ======================================================================
- * Name: q_query
- * Description: Connects to KDB server, sends the scan command, returns the scan
- * results and converts to QByteArray
- * Returns: logs -> QByteArray
- * =====================================================================================
- */
- QByteArray q_query(char* qinput,bool isdir)
- {
- K result,line,directory_result;
- QByteArray logs;
- unsigned char *str;
- const char* str1;
- qconn *conn = new qconn; /* Create new Q connection */
- if( conn->isConnected() ){ /* If connected then query */
- result = conn->sync_query(qinput);
- delete conn;
- }
- else { /* Else return error */
- delete conn;
- logs = "Error connecting to database\nCheck error logs for more details";
- return logs;
- }
- if(isdir){
- for(int j=0;j<result->n;j++){ /* Iterate through K array of K objects */
- directory_result=kK(result)[j];
- for(int i=0;i<directory_result->n;i++){ /* Grab object */
- line=kK(directory_result)[i];
- int s = line->n; /* Find length */
- str = (kC(line)); /* Accessor kC converts to char */
- str[s] = '\0';
- str1 = reinterpret_cast<const char*>(str); /* Convert to signed */
- logs.append(str1); /* Append to log file */
- logs.append('\n');
- }
- logs.append('\n');
- }
- }
- // Same process as above but for a single K object (rather than an array of objects)
- else{
- for(int i=0;i<result->n;i++){
- line=kK(result)[i];
- int s = line->n;
- str = (kC(line));
- str[s] = '\0';
- str1 = reinterpret_cast<const char*>(str);
- logs.append(str1);
- logs.append('\n');
- }
- }
- return logs;
- }
- /*
- * === FUNCTION ======================================================================
- * Name: file_thread
- * Description: Builds file directory and path strings
- * Builds Q function to be sent to KDB server
- * Launches query in a separate thread
- * =====================================================================================
- */
- void qguiApp::file_thread()
- {
- string path,fname,dir,input;
- if(file_2->toPlainText().toStdString() == ""){ /* Check if a file has been selected */
- fileConsole->setText("Select file");
- return;
- }
- path=(file_2->toPlainText()).toStdString(); /* Convert path to directory and path */
- fname=path.substr(path.find_last_of("/") + 1);
- dir=path.substr(0,path.find_last_of("/"));
- // Build the query to be sent to Q
- input = "qscan[\"" + fname + "\";\"" + dir + "\"]";
- char * qinput = new char[input.size() + 1];
- copy(input.begin(),input.end(),qinput);
- qinput[input.size()] = '\0';
- *fileFuture = QtConcurrent::run( file_query,qinput ); /* Launch scan thread */
- fileWatcher->setFuture(*fileFuture);
- }
- /*
- * === FUNCTION ======================================================================
- * Name: file_logs
- * Description: Gets file inspection query results
- * Displays results in console
- * =====================================================================================
- */
- void qguiApp::file_logs()
- {
- QByteArray flogs = fileFuture->result(); /* Display file inspection results */
- fileConsole->setText(flogs);
- }
- /*
- * === FUNCTION ======================================================================
- * Name: file_query
- * Description: Connects to KDB database
- * Adjusts settings NOT to scan the file and just get file info
- * Convert results to QByteArray
- * Returns: logs -> QByteArray, contains query results
- * =====================================================================================
- */
- QByteArray file_query(char* qinput)
- {
- K result,line;
- QByteArray logs;
- unsigned char *str;
- const char *str1;
- qconn *conn = new qconn; /* Make KDB connection */
- if( conn->isConnected() ){
- conn->async_query("t:settings[`verbose`md5`virus]"); /* Save settings state */
- conn->async_query("settings[`verbose`md5`virus]:100b"); /* Turn scanning off */
- result=conn->sync_query(qinput); /* Query file */
- conn->async_query("settings[`verbose`md5`virus]:t"); /* Restore save state */
- delete conn; /* Close connection */
- }
- else { /* Deal with error connecting to KDB */
- delete conn;
- logs = "Error connecting to database\nCheck error logs for more details";
- return logs;
- }
- for(int i=0;i<5;i++){ /* Convert results to QByteArray */
- line=kK(result)[i];
- int s = line->n;
- str = (kC(line));
- str[s] = '\0';
- str1 = reinterpret_cast<const char*>(str);
- logs.append(str1);
- logs.append('\n');
- }
- return logs;
- }
- /*
- * === FUNCTION ======================================================================
- * Name: clearScan
- * Description: Clears the console screen
- * =====================================================================================
- */
- void qguiApp::clearScan()
- {
- scanConsole->clear();
- }
- /*
- * === FUNCTION ======================================================================
- * Name: clearFile
- * Description: Clears the file inspectors console screen
- * =====================================================================================
- */
- void qguiApp::clearFile()
- {
- fileConsole->clear();
- }
- /*
- * === FUNCTION ======================================================================
- * Name: updateSettings
- * Description: Takes the values on the settings page and updates the KDB database
- * with the current settings.
- * =====================================================================================
- */
- void qguiApp::updateSettings()
- {
- bool settings_verbose,settings_md5,settings_updates,settings_virus;
- string sverbose,smd5,supdates,svirus,query;
- settings_md5 = settingsMd5->isChecked(); /* Get settings checked */
- settings_virus= settingsVirus->isChecked();
- settings_updates= settingsUpdates->isChecked();
- settings_verbose = settingsVerbose->isChecked();
- if(settings_md5){smd5="1";}else {smd5="0";} /* Used to build Q update query */
- if(settings_virus){svirus="1";}else {svirus="0";}
- if(settings_verbose){sverbose="1";}else {sverbose="0";}
- if(settings_updates){supdates="1";}else {supdates="0";}
- // Build the Q query
- query = "qsettings["+sverbose+ " " +svirus+ " " +smd5+ " " + supdates+"]";
- char * qinput = new char[query.size() + 1];
- copy(query.begin(),query.end(),qinput);
- qinput[query.size()] = '\0';
- qconn *conn = new qconn; /* Connect to KDB server */
- if(conn->isConnected()){
- conn->async_query( qinput );
- }
- delete conn;
- updateSettingsButton->setEnabled(false); /* After a save, disable the button */
- }
- /*
- * === FUNCTION ======================================================================
- * Name: loadSettings
- * Description: When a tab is changed, the current settings saved in the KDB database
- * are updated.
- * =====================================================================================
- */
- void qguiApp::loadSettings()
- {
- bool verbose,md5,virus,updates;
- K result;
- qconn *conn = new qconn; /* Connect to Q */
- if(conn->isConnected()){
- result = conn->sync_query("settings[`verbose`virus`md5`updates]");
- verbose = kG(result)[0]; /* Get the settings from the results */
- virus = kG(result)[1];
- md5 = kG(result)[2];
- updates = kG(result)[3];
- settingsMd5->setChecked(md5); /* Configure the settings page */
- settingsVirus->setChecked(virus);
- settingsUpdates->setChecked(updates);
- settingsVerbose->setChecked(verbose);
- }
- delete conn;
- updateSettingsButton->setEnabled(false);
- }
- /*
- * === FUNCTION ======================================================================
- * Name: showSave
- * Description: Shows the save button on the settings page when the settings in the
- * KDB database do not match the GUI selected settings
- * =====================================================================================
- */
- void qguiApp::showSave()
- {
- bool verbose,md5,virus,updates,same;
- K result;
- qconn *conn = new qconn; /* Connect to KDB server */
- if(conn->isConnected()){
- // Get the current settings
- result = conn->sync_query("settings[`verbose`virus`md5`updates]");
- verbose = kG(result)[0];
- virus = kG(result)[1];
- md5 = kG(result)[2];
- updates = kG(result)[3];
- // When the checked values equal the KDB settings values same is true
- same = (verbose!=settingsVerbose->isChecked()) && (virus!=settingsVirus->isChecked()) &&
- (md5!=settingsMd5->isChecked()) && (updates!=settingsUpdates->isChecked());
- // Show the button if the KDB settings dont match GUI settings
- if(!same){updateSettingsButton->setEnabled(true);}
- }
- delete conn;
- }
- /*
- * === FUNCTION ======================================================================
- * Name: getPathOrDir
- * Description: Get the selected scan type from the dropbox (file or directory)
- * Open a file explorer allowing the user to choose file or directory
- * Load the file or directory into the textbox
- * =====================================================================================
- */
- void qguiApp::getPathOrDir()
- {
- QString path;
- QString type;
- type = scanType->currentText(); /* Get drop menu selection */
- if(type == "File"){
- path = QFileDialog::getOpenFileName( /* Open file explorer */
- this,
- "Choose a file to scan",
- QString::null,
- QString::null);
- }
- else {
- path = QFileDialog::getExistingDirectory( /* Open directory explorer */
- this,
- "Choose a directory",
- QString::null
- );
- }
- file->setText( path ); /* Set file path in text box */
- }
- /*
- * === FUNCTION ======================================================================
- * Name: getPath
- * Description: Opens the file explorer and sets a text box with the path chosen
- * =====================================================================================
- */
- void qguiApp::getPath()
- {
- QString path;
- path = QFileDialog::getOpenFileName( /* Open explorer */
- this,
- "Choose a file to scan",
- QString::null,
- QString::null);
- file_2->setText( path ); /* Set text */
- }
- /*
- * === FUNCTION ======================================================================
- * Name: scanTypeChanged
- * Description: When the drop down menu to select a file or directory is changed this
- * function empties the text box
- * =====================================================================================
- */
- void qguiApp::scanTypeChanged()
- {
- file->setText("");
- }
- /*
- * === FUNCTION ======================================================================
- * Name: showHelp
- * Description: Dispalys a help file in the console window
- * =====================================================================================
- */
- void qguiApp::showHelp()
- {
- QFile userGuide("doc/manual.txt"); /* Read in the file */
- userGuide.open(QIODevice::ReadOnly);
- QByteArray userGuideText = userGuide.readAll(); /* and display... */
- scanConsole->setText( userGuideText );
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement