Переглянути джерело

Merge branch '87-us48-reset-signal-for-covert-channel-protocol' into 'develop'

US48: Reset signal for covert channel protocol

Closes #87

See merge request tobias.wach/ccats!93
Sander, Paul 4 роки тому
батько
коміт
e8db652465

+ 28 - 16
daemon/include/CovertChannel/BidirectionalChannels.hpp

@@ -42,33 +42,24 @@ public:
 	 */
 	virtual ~BidirectionalChannels() {}
 
+	/* ChannelControls */
+
 	/**
-	 * Send a file over the covert channel.
+	 * Starts sending a file.
+	 *
+	 * Starts sending a file if no transmission is running and the file exists.
 	 *
 	 * @param fileName name of the file in the file directory
 	 * @return true - file will be sent | false - file was not accepted
 	 */
-	virtual bool sendFile(const std::string &fileName) {
-		if constexpr (PASSIVE) {
-			return false;
-		} else {
-			transferStart = std::time(nullptr);
-			return protocol.sendFile(fileName);
-		}
-	}
+	virtual bool sendFile(const std::string &fileName) { return protocol.sendFile(fileName); }
 
 	/**
 	 * Get the progress
 	 *
 	 * @return progress counters
 	 */
-	virtual std::pair<uint32_t, uint32_t> getProgress() {
-		if (isTransferRunning()) {
-			return protocol.getProgress();
-		} else {
-			return std::pair<uint32_t, uint32_t>(0, 0);
-		}
-	}
+	virtual std::pair<uint32_t, uint32_t> getProgress() { return protocol.getProgress(); }
 
 	/**
 	 * Test if a transfer is running
@@ -77,6 +68,27 @@ public:
 	 */
 	virtual bool isTransferRunning() { return protocol.isTransferRunning(); }
 
+	/**
+	 * Resets state and sets reset flag so a reset signal is sent in the next packet
+	 */
+	virtual void reset() { protocol.reset(); }
+
+	/**
+	 * Test if a transfer is running
+	 *
+	 * @return true - a transfer runs | false - no transfer runs
+	 */
+	virtual std::time_t getTransferStart() { return protocol.getTransferStart(); }
+
+	/**
+	 * Get file name of the file which is currently be sent or received.
+	 *
+	 * @return file name
+	 */
+	virtual std::string getFileName() { return protocol.getFileName(); };
+
+	/* =============== */
+
 protected:
 	/**
 	 * protocol used to transmit data

+ 18 - 1
daemon/include/CovertChannel/ChannelControls.h

@@ -27,7 +27,7 @@ public:
 	 *
 	 * @return start time of the transfer
 	 */
-	virtual std::time_t getTransferStart();
+	virtual std::time_t getTransferStart() = 0;
 
 	/**
 	 * Test if a transfer is running
@@ -36,11 +36,28 @@ public:
 	 */
 	virtual bool isTransferRunning() = 0;
 
+	/**
+	 * Resets the state of the channel
+	 */
+	virtual void reset() = 0;
+
+	/**
+	 * Get file name of the file which is currently be sent or received.
+	 *
+	 * @return file name
+	 */
+	virtual std::string getFileName() = 0;
+
 protected:
 	/**
 	 * Time when the transfer was started with sendFile
 	 */
 	std::time_t transferStart;
+
+	/**
+	 * file name of the file wich is being sent or received
+	 */
+	std::string fileName;
 };
 
 #endif

+ 0 - 22
daemon/include/CovertChannel/CovertChannel.h

@@ -36,14 +36,6 @@ public:
 	 */
 	virtual ~CovertChannel();
 
-	/**
-	 * Send a file over the covert channel.
-	 *
-	 * @param fileName name of the file in the file directory
-	 * @return true - file will be sent | false - file was not accepted
-	 */
-	virtual bool sendFile(const std::string &fileName);
-
 	/**
 	 * Start sniffing on the interface.
 	 *
@@ -63,20 +55,6 @@ public:
 	void setFilter(const std::string &innerForwardFilter = "", const std::string &outerForwardFilter = "", const std::string &innerChannelFilter = "",
 	               const std::string &outerChannelFilter = "");
 
-	/**
-	 * Get the progress
-	 *
-	 * @return progress counters
-	 */
-	virtual std::pair<uint32_t, uint32_t> getProgress() = 0;
-
-	/**
-	 * Test if a transfer is running
-	 *
-	 * @return true - a transfer runs | false - no transfer runs
-	 */
-	virtual bool isTransferRunning();
-
 protected:
 	/**
 	 * Handler for sniffed packets filterd to forward from the outer network.

+ 40 - 0
daemon/include/CovertChannel/ForwardChannel.h

@@ -26,6 +26,18 @@ public:
 	 */
 	virtual ~ForwardChannel();
 
+	/* ChannelControls */
+
+	/**
+	 * Starts sending a file.
+	 *
+	 * Starts sending a file if no transmission is running and the file exists.
+	 *
+	 * @param fileName name of the file in the file directory
+	 * @return true - file will be sent | false - file was not accepted
+	 */
+	virtual bool sendFile(const std::string &fileName);
+
 	/**
 	 * Get the progress
 	 *
@@ -33,6 +45,34 @@ public:
 	 */
 	virtual std::pair<uint32_t, uint32_t> getProgress();
 
+	/**
+	 * Test if a transfer is running
+	 *
+	 * @return true - a transfer runs | false - no transfer runs
+	 */
+	virtual bool isTransferRunning();
+
+	/**
+	 * Resets state and sets reset flag so a reset signal is sent in the next packet
+	 */
+	virtual void reset();
+
+	/**
+	 * Test if a transfer is running
+	 *
+	 * @return true - a transfer runs | false - no transfer runs
+	 */
+	virtual std::time_t getTransferStart();
+
+	/**
+	 * Get file name of the file which is currently be sent or received.
+	 *
+	 * @return file name
+	 */
+	virtual std::string getFileName();
+
+	/* =============== */
+
 protected:
 	/**
 	 * Handler for sniffed packets filterd to forward from the outer network.

+ 105 - 39
daemon/include/CovertChannel/Protocols/CovertProtocol.hpp

@@ -6,8 +6,12 @@
 #include <string>
 #include <type_traits>
 
-#include "../../../include/Config.h"
-#include "../../../include/Queue.h"
+#include <boost/filesystem.hpp>
+
+#include "../../Config.h"
+#include "../../Notifications.h"
+#include "../../Queue.h"
+#include "../ChannelControls.h"
 
 /**
  * @class CovertProtocol
@@ -19,7 +23,7 @@
  * @param N number of bytes which can be used to transmit data
  * @param PASSIVE passive mode
  */
-template <int N, bool PASSIVE> class CovertProtocol {
+template <int N, bool PASSIVE> class CovertProtocol : public ChannelControls {
 	static_assert(N >= 1);
 
 public:
@@ -35,33 +39,6 @@ public:
 	 */
 	~CovertProtocol() { file.close(); }
 
-	/**
-	 * Starts sending a file.
-	 *
-	 * Starts sending a file if no transmission is running and the file exists.
-	 *
-	 * @param fileName name of the file in the file directory
-	 * @return true - file will be sent | false - file was not accepted
-	 */
-	bool sendFile(const std::string &fileName) {
-		static_assert(!PASSIVE);
-
-		if (state != ProtocolState::idle || file.is_open()) {
-			return false;
-		}
-
-		file.open(fileDirectory + fileName, std::ios::in);
-		if (file.is_open()) {
-			file.close();
-			this->fileName = fileName;
-			state = ProtocolState::fileNameSize;
-			std::cout << "starting sending file \"" << fileName << "\"" << std::endl;
-			return true;
-		} else {
-			return false;
-		}
-	}
-
 	/**
 	 * send encodes the data into the data array
 	 *
@@ -103,8 +80,10 @@ public:
 				file.open(fileDirectory + fileName, std::ios::in | std::ios::binary | std::ios::ate);
 				if (!file.is_open()) {
 					file.close();
-					std::cerr << "File \"" << fileName << "\" does exists. Error state!!!" << std::endl;
-					state = ProtocolState::error;
+					std::cerr << "File \"" << fileName << "\" does exists. Resetting!!!" << std::endl;
+					Notifications::newNotification("File \"" + fileName + "\" does not exists. Skipping.");
+					// state = ProtocolState::error;
+					Queue::channel->reset();
 					return;
 				}
 
@@ -156,6 +135,7 @@ public:
 				file.close();
 				state = ProtocolState::idle;
 				std::cout << "finished sending file \"" << fileName << "\"" << std::endl;
+				Notifications::newNotification("Finished sending file \"" + fileName + "\".");
 
 				// schedule next file transfer
 				Queue::schedule();
@@ -164,7 +144,7 @@ public:
 			break;
 
 		case ProtocolState::error:
-
+			Queue::channel->reset();
 			break;
 		}
 
@@ -192,11 +172,13 @@ public:
 
 			// no break because the first data received is the filename size
 		case ProtocolState::fileNameSize:
+			Notifications::newNotification("Incoming transmission.");
 			std::cout << "incoming file transmission" << std::endl;
 
 			fileNameSize = data[0];
 			fileNamePosition = 0;
 			fileName = "";
+			transferStart = std::time(nullptr);
 			state = ProtocolState::fileName;
 			break;
 
@@ -217,8 +199,10 @@ public:
 				file.open(fileDirectory + fileName, std::ios::in);
 				if (file.is_open()) {
 					file.close();
-					std::cerr << "File \"" << fileName << "\" already exists. Error state!!!" << std::endl;
-					state = ProtocolState::error;
+					std::cerr << "File \"" << fileName << "\" already exists. Resetting!!!" << std::endl;
+					Notifications::newNotification("File \"" + fileName + "\" already exists. Skipping.");
+					// state = ProtocolState::error;
+					Queue::channel->reset();
 					return;
 				}
 
@@ -226,8 +210,10 @@ public:
 
 				file.open(fileDirectory + fileName, std::ios::out | std::ios::binary | std::ios::app);
 				if (!file.is_open()) {
-					std::cerr << "File \"" << fileName << "\" could not be opened! Error state!!!" << std::endl;
-					state = ProtocolState::error;
+					std::cerr << "File \"" << fileName << "\" could not be opened! Resetting!!!" << std::endl;
+					Notifications::newNotification("File \"" + fileName + "\" could not be written. Skipping.");
+					// state = ProtocolState::error;
+					Queue::channel->reset();
 					return;
 				}
 
@@ -236,6 +222,7 @@ public:
 				state = ProtocolState::dataSize;
 
 				std::cout << "starting receiving file \"" << fileName << "\"" << std::endl;
+				Notifications::newNotification("Receiving file \"" + fileName + "\".");
 			}
 
 			break;
@@ -280,6 +267,7 @@ public:
 				state = ProtocolState::idle;
 
 				std::cout << "finished receiving file \"" << fileName << "\"" << std::endl;
+				Notifications::newNotification("Finished receiving file \"" + fileName + "\".");
 			}
 
 			break;
@@ -289,6 +277,39 @@ public:
 		}
 	}
 
+	/* ChannelControls */
+
+	/**
+	 * Starts sending a file.
+	 *
+	 * Starts sending a file if no transmission is running and the file exists.
+	 *
+	 * @param fileName name of the file in the file directory
+	 * @return true - file will be sent | false - file was not accepted
+	 */
+	virtual bool sendFile(const std::string &fileName) {
+		if constexpr (PASSIVE) {
+			return false;
+		}
+
+		if (state != ProtocolState::idle || file.is_open()) {
+			return false;
+		}
+
+		file.open(fileDirectory + fileName, std::ios::in);
+		if (file.is_open()) {
+			file.close();
+			this->fileName = fileName;
+			transferStart = std::time(nullptr);
+			state = ProtocolState::fileNameSize;
+			Notifications::newNotification("Start sending file \"" + fileName + "\".");
+			std::cout << "starting sending file \"" << fileName << "\"" << std::endl;
+			return true;
+		} else {
+			return false;
+		}
+	}
+
 	/**
 	 * Get the progress
 	 *
@@ -309,6 +330,44 @@ public:
 	 */
 	virtual bool isTransferRunning() { return state != ProtocolState::idle; }
 
+	/**
+	 * Resets protocol state
+	 */
+	virtual void reset() {
+		file.close();
+
+		if (PASSIVE && state == ProtocolState::data) {
+			// delete file if in passive mode and data has been received
+			deleteFile(fileName);
+			Notifications::newNotification("Transfer of file \"" + fileName + "\" was aborted.");
+		}
+
+		state = ProtocolState::idle;
+		dataSize = 0;
+		dataPosition = 0;
+		fileNameSize = 0;
+		fileNamePosition = 0;
+		fileName = "";
+
+		Queue::schedule();
+	}
+
+	/**
+	 * Test if a transfer is running
+	 *
+	 * @return true - a transfer runs | false - no transfer runs
+	 */
+	virtual std::time_t getTransferStart() { return transferStart; }
+
+	/**
+	 * Get file name of the file which is currently be sent or received.
+	 *
+	 * @return file name
+	 */
+	virtual std::string getFileName() { return fileName; };
+
+	/* =============== */
+
 private:
 	/**
 	 * folder of the files
@@ -353,9 +412,16 @@ private:
 	uint8_t fileNamePosition;
 
 	/**
-	 * name of the file to be sent/received
+	 * Deletes a file
 	 */
-	std::string fileName;
+	void deleteFile(const std::string &fileName) {
+		std::string fname = this->fileDirectory;
+		fname.append(fileName);
+
+		if (boost::filesystem::exists(fname)) {
+			boost::filesystem::remove(fname);
+		}
+	}
 };
 
 #endif

+ 70 - 22
daemon/include/CovertChannel/Protocols/CovertProtocolBidirectional.hpp

@@ -2,10 +2,10 @@
 #define COVERTPROTOCOLBIDIRECTIONAL_H
 
 #include <fstream>
-#include <iostream>
 #include <string>
 #include <type_traits>
 
+#include "../ChannelControls.h"
 #include "CovertProtocol.hpp"
 
 /**
@@ -19,42 +19,36 @@
  * @param N number of bytes which can be used to transmit data
  * @param PASSIVE passive mode
  */
-template <int N, bool PASSIVE> class CovertProtocolBidirectional {
+template <int N, bool PASSIVE> class CovertProtocolBidirectional : public ChannelControls {
 	static_assert(N >= 2);
 
 public:
 	/**
 	 * CovertProtocolBidirectional constructor
 	 */
-	CovertProtocolBidirectional() : segment(PASSIVE ? 1 : 0) { lastData = new uint8_t[N](); }
+	CovertProtocolBidirectional() : segment(PASSIVE ? 1 : 0) {
+		lastData = new uint8_t[N]();
+		protocol.reset();
+	}
 
 	/**
 	 * CovertProtocol destructor
 	 */
 	~CovertProtocolBidirectional() { delete[](lastData); }
 
-	/**
-	 * Starts sending a file.
-	 *
-	 * Starts sending a file if no transmission is running and the file exists.
-	 *
-	 * @param fileName name of the file in the file directory
-	 * @return true - file will be sent | false - file was not accepted
-	 */
-	bool sendFile(const std::string &fileName) {
-		if constexpr (PASSIVE) {
-			return false;
-		}
-
-		return protocol.sendFile(fileName);
-	}
-
 	/**
 	 * send encodes the data into the data array
 	 *
 	 * @param data must be an array of size N
 	 */
 	void send(uint8_t *const data) {
+		if (sendResetFlag) {
+			sendResetFlag = false;
+			data[0] = (segment << 6) | 1;
+			std::memset(data + 1, 0, N - 1);
+			return;
+		}
+
 		if (sendSegment()) {
 			std::memcpy(data, lastData, N);
 			return;
@@ -77,8 +71,12 @@ public:
 	 */
 	void receive(const uint8_t *const data) {
 		uint8_t seg = data[0] >> 6;
+		bool reset = data[0] & 1;
 
-		std::cerr << "segment: " << (int)segment << "\tack: " << (int)lastACKedSegment << "\tseg: " << (int)seg << std::endl;
+		if (reset) {
+			resetState();
+			return;
+		}
 
 		if (receiveSegment(seg)) {
 			return;
@@ -89,6 +87,18 @@ public:
 		}
 	}
 
+	/* ChannelControls */
+
+	/**
+	 * Starts sending a file.
+	 *
+	 * Starts sending a file if no transmission is running and the file exists.
+	 *
+	 * @param fileName name of the file in the file directory
+	 * @return true - file will be sent | false - file was not accepted
+	 */
+	virtual bool sendFile(const std::string &fileName) { return protocol.sendFile(fileName); }
+
 	/**
 	 * Get the progress
 	 *
@@ -103,6 +113,30 @@ public:
 	 */
 	virtual bool isTransferRunning() { return protocol.isTransferRunning(); }
 
+	/**
+	 * Resets state and sets reset flag so a reset signal is sent in the next packet
+	 */
+	virtual void reset() {
+		sendResetFlag = true;
+		resetState();
+	}
+
+	/**
+	 * Test if a transfer is running
+	 *
+	 * @return true - a transfer runs | false - no transfer runs
+	 */
+	virtual std::time_t getTransferStart() { return protocol.getTransferStart(); }
+
+	/**
+	 * Get file name of the file which is currently be sent or received.
+	 *
+	 * @return file name
+	 */
+	virtual std::string getFileName() { return protocol.getFileName(); };
+
+	/* =============== */
+
 private:
 	/**
 	 * current segment counter
@@ -124,6 +158,11 @@ private:
 	 */
 	CovertProtocol<N - 1, PASSIVE> protocol;
 
+	/**
+	 * Sends a reset signal on next send call
+	 */
+	bool sendResetFlag = true;
+
 	/**
 	 * Evaluates received segment number and increases own segment number if necessary
 	 *
@@ -137,7 +176,6 @@ private:
 				lastACKedSegment = seg;
 				return false;
 			} else {
-				std::cerr << "Throwing this packet away" << std::endl;
 				return true;
 			}
 		} else {
@@ -146,7 +184,6 @@ private:
 				lastACKedSegment = increaseSegment(lastACKedSegment, 1);
 				return false;
 			} else {
-				std::cerr << "Throwing this packet away" << std::endl;
 				return true;
 			}
 		}
@@ -171,6 +208,17 @@ private:
 	 * @return seg + inc
 	 */
 	inline uint8_t increaseSegment(uint8_t seg, uint8_t inc) { return seg + inc & 0x3; }
+
+	/**
+	 * Resets the state of the protocol.
+	 * This method can / should only be called from this class.
+	 */
+	void resetState() {
+		protocol.reset();
+		segment = (PASSIVE ? 1 : 0);
+		lastACKedSegment = 0;
+		std::memset(lastData, 0, N);
+	}
 };
 
 #endif

+ 5 - 4
daemon/include/Queue.h

@@ -30,14 +30,15 @@ bool remove(const std::string &file);
 void schedule();
 
 /**
- * The queue. Stores filenames. Acts as FIFO.
+ * Returns the name of the file of the current transfer. Empty otherwise.
+ * @return file name
  */
-extern std::deque<std::string> queue;
+std::string curTransfer();
 
 /**
- * Holds the name of the file of the current transfer. Empty otherwise.
+ * The queue. Stores filenames. Acts as FIFO.
  */
-extern std::string curTransfer;
+extern std::deque<std::string> queue;
 
 /**
  * Mutex to lock queue while editing it.

+ 1 - 1
daemon/src/CMakeLists.txt

@@ -2,7 +2,7 @@ cmake_minimum_required(VERSION 2.8)
 
 set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
 
-add_executable(ccats src/main.cpp src/Server.cpp src/base64.cpp src/JsonCommander.cpp src/FileManager.cpp src/UserManager.cpp src/Config.cpp src/CovertChannel/CovertChannel.cpp src/CovertChannel/ForwardChannel.cpp src/Notifications.cpp src/Queue.cpp src/CovertChannel/ChannelControls.cpp ../libs/libbcrypt/bcrypt.c ../libs/libbcrypt/crypt_blowfish/crypt_blowfish.c ../libs/libbcrypt/crypt_blowfish/crypt_gensalt.c ../libs/libbcrypt/crypt_blowfish/wrapper.c)
+add_executable(ccats src/main.cpp src/Server.cpp src/base64.cpp src/JsonCommander.cpp src/FileManager.cpp src/UserManager.cpp src/Config.cpp src/CovertChannel/CovertChannel.cpp src/CovertChannel/ForwardChannel.cpp src/Notifications.cpp src/Queue.cpp ../libs/libbcrypt/bcrypt.c ../libs/libbcrypt/crypt_blowfish/crypt_blowfish.c ../libs/libbcrypt/crypt_blowfish/crypt_gensalt.c ../libs/libbcrypt/crypt_blowfish/wrapper.c)
 
 # dependencies used by server only
 find_package(libtins 4.2 REQUIRED)

+ 0 - 3
daemon/src/CovertChannel/ChannelControls.cpp

@@ -1,3 +0,0 @@
-#include "../../include/CovertChannel/ChannelControls.h"
-
-std::time_t ChannelControls::getTransferStart() { return transferStart; }

+ 0 - 4
daemon/src/CovertChannel/CovertChannel.cpp

@@ -73,7 +73,3 @@ bool CovertChannel::handleForwardFromInner(Tins::PDU &pdu) {
 
 	return true;
 }
-
-bool CovertChannel::sendFile(const std::string &fileName) { return false; }
-
-bool CovertChannel::isTransferRunning() { return false; }

+ 14 - 0
daemon/src/CovertChannel/ForwardChannel.cpp

@@ -8,4 +8,18 @@ bool ForwardChannel::handleChannelFromOuter(Tins::PDU &pdu) { return false; }
 
 bool ForwardChannel::handleChannelFromInner(Tins::PDU &pdu) { return false; }
 
+/* ChannelControls */
+
+bool ForwardChannel::sendFile(const std::string &fileName) { return false; }
+
 std::pair<uint32_t, uint32_t> ForwardChannel::getProgress() { return std::pair<uint32_t, uint32_t>(0, 0); }
+
+bool ForwardChannel::isTransferRunning() { return false; }
+
+void ForwardChannel::reset() {}
+
+std::time_t ForwardChannel::getTransferStart() { return 0; }
+
+std::string ForwardChannel::getFileName() { return ""; }
+
+/* =============== */

+ 7 - 2
daemon/src/JsonCommander.cpp

@@ -560,10 +560,15 @@ JsonCommander::Response JsonCommander::executeExtendedStatus(const Json::Value &
 	index = 0;
 	if (Queue::channel != nullptr && Queue::channel->isTransferRunning()) {
 		response.json["transfersserverserver"][index]["type"] = Config::getValue("passiveMode").compare("true") == 0 ? "download" : "upload";
-		response.json["transfersserverserver"][index]["file"] = Queue::curTransfer;
+		response.json["transfersserverserver"][index]["file"] = Queue::curTransfer();
 
 		auto rawprogress = Queue::channel->getProgress();
-		double d = ((double)rawprogress.first / (double)rawprogress.second);
+		double d;
+		if (rawprogress.second == 0)
+			d = 0.0;
+		else
+			d = ((double)rawprogress.first / (double)rawprogress.second);
+
 		int progress = (int)(d * 100);
 		response.json["transfersserverserver"][index]["progress"] = progress;
 

+ 19 - 10
daemon/src/Queue.cpp

@@ -1,9 +1,9 @@
 #include "../include/Queue.h"
+#include "../include/Notifications.h"
 #include <algorithm>
 
 namespace Queue {
 std::deque<std::string> queue;
-std::string curTransfer = "";
 std::mutex mtx;
 ChannelControls *channel;
 } // namespace Queue
@@ -18,8 +18,9 @@ bool Queue::push(const std::string &file) {
 	queue.push_back(file);
 	mtx.unlock();
 
-	// TODO run in extra thread??
-	if (curTransfer.compare("") == 0) {
+	Notifications::newNotification("File \"" + file + "\" queued.");
+
+	if (curTransfer().compare("") == 0) {
 		schedule();
 	}
 
@@ -27,9 +28,11 @@ bool Queue::push(const std::string &file) {
 }
 
 bool Queue::remove(const std::string &file) {
-	if (curTransfer.compare(file) == 0) {
-		// TODO check if remove is allowed
-		return false;
+	if (curTransfer().compare(file) == 0) {
+		// Reset channel and remove from queue
+		channel->reset();
+		Notifications::newNotification("Transfer of file \"" + file + "\" was aborted.");
+		return true;
 	} else {
 		mtx.lock();
 		auto it = std::find(queue.begin(), queue.end(), file);
@@ -47,20 +50,26 @@ void Queue::schedule() {
 		mtx.lock();
 		std::string file = queue.front();
 		queue.pop_front();
-		curTransfer = file;
 
 		// success is false if file could not be sent or found
-		bool success = channel->sendFile(curTransfer);
+		bool success = channel->sendFile(file);
 		mtx.unlock();
 
 		if (!success) {
+			Notifications::newNotification("File \"" + file + "\" could not be sent.");
 			schedule();
 		}
-
 		// don't wait until transer finished because schedule must be called again
 	} else {
 		mtx.lock();
-		curTransfer = "";
 		mtx.unlock();
 	}
 }
+
+std::string Queue::curTransfer() {
+	if (channel == nullptr || !channel->isTransferRunning()) {
+		return "";
+	}
+
+	return channel->getFileName();
+}

+ 0 - 4
daemon/src/main.cpp

@@ -89,10 +89,6 @@ int main(int argc, char *argv[]) {
 			covertchannel = new TCPOptionCustomChannel<8, false>(innerInterface, outerInterface, ownIP, targetIP, targetPort);
 		}
 
-		// test sending file
-		if (passiveMode != "true" && sendFile != "")
-			covertchannel->sendFile(sendFile);
-
 		// covertchannel = new ForwardChannel(innerInterface, outerInterface);
 		covertchannel->startSniffing();
 	} else if (covertChannelMode == "forward") {

+ 1 - 1
daemon/test/CMakeLists.txt

@@ -12,7 +12,7 @@ find_package(GMock REQUIRED)
 include_directories(${Boost_INCLUDE_DIR} ${JSONCPP_INCLUDE_DIRS} ${GTEST_INCLUDE_DIRS} ${GMOCK_INCLUDE_DIRS})
 
 # Add test cpp file
-add_executable(jsonCommanderTest test/JsonCommanderTest.cpp src/JsonCommander.cpp src/FileManager.cpp src/base64.cpp test/ConfigMock.cpp test/UserManagerMock.cpp src/Notifications.cpp test/QueueMock.cpp src/CovertChannel/ChannelControls.cpp)
+add_executable(jsonCommanderTest test/JsonCommanderTest.cpp src/JsonCommander.cpp src/FileManager.cpp src/base64.cpp test/ConfigMock.cpp test/UserManagerMock.cpp src/Notifications.cpp test/QueueMock.cpp)
 target_link_libraries(jsonCommanderTest ${CMAKE_THREAD_LIBS_INIT} ${Boost_LIBRARIES} ${JSONCPP_LIBRARIES} ${GTEST_BOTH_LIBRARIES} ${GMOCK_BOTH_LIBRARIES})
 
 add_test(

+ 2 - 0
daemon/test/ChannelControlsMock.h

@@ -15,6 +15,8 @@ public:
 	MOCK_METHOD((std::pair<uint32_t, uint32_t>), getProgress, (), (override));
 	MOCK_METHOD(std::time_t, getTransferStart, (), (override));
 	MOCK_METHOD(bool, isTransferRunning, (), (override));
+	MOCK_METHOD(void, reset, (), (override));
+	MOCK_METHOD(std::string, getFileName, (), (override));
 };
 
 #endif

+ 3 - 3
daemon/test/JsonCommanderTest.cpp

@@ -4,9 +4,9 @@
 #include "../include/Config.h"
 #include "../include/JsonCommander.h"
 #include "../include/Notifications.h"
-#include "../include/Queue.h"
 #include "ChannelControlsMock.h"
 #include "FileManagerMock.h"
+#include "QueueMock.h"
 
 namespace {
 /* Version tests */
@@ -1319,7 +1319,7 @@ TEST(ExtendedStatus, ServerServerDownload) {
 	ChannelControlsMock channelControls;
 	Queue::channel = &channelControls;
 	Queue::queue.clear();
-	Queue::curTransfer = "a.txt";
+	Queue::fileName = "a.txt";
 	Config::storage.clear();
 	Config::storage.insert(std::pair<std::string, std::string>("passiveMode", "true"));
 	Config::storage.insert(std::pair<std::string, std::string>("covertChannelMode", "m"));
@@ -1355,7 +1355,7 @@ TEST(ExtendedStatus, ServerServerUpload) {
 	ChannelControlsMock channelControls;
 	Queue::channel = &channelControls;
 	Queue::queue.clear();
-	Queue::curTransfer = "a.txt";
+	Queue::fileName = "a.txt";
 	Config::storage.clear();
 	Config::storage.insert(std::pair<std::string, std::string>("passiveMode", "false"));
 	Config::storage.insert(std::pair<std::string, std::string>("covertChannelMode", "m"));

+ 3 - 1
daemon/test/QueueMock.cpp

@@ -2,7 +2,7 @@
 
 namespace Queue {
 std::deque<std::string> queue;
-std::string curTransfer = "";
+std::string fileName = "";
 ChannelControls *channel;
 } // namespace Queue
 
@@ -15,3 +15,5 @@ bool Queue::push(const std::string &file) {
 bool Queue::remove(const std::string &file) { return true; }
 
 void Queue::schedule() {}
+
+std::string Queue::curTransfer() { return fileName; }

+ 10 - 0
daemon/test/QueueMock.h

@@ -0,0 +1,10 @@
+#ifndef QUEUE_MOCK_H
+#define QUEUE_MOCK_H
+
+#include "../include/Queue.h"
+
+namespace Queue {
+extern std::string fileName;
+}
+
+#endif