Selaa lähdekoodia

Merge branch 'us41-2-covert-channel-queueing-cli' into 'develop'

US41.2: Covert Channel Queueing (CLI)

Closes #78

See merge request tobias.wach/ccats!72
Sander, Paul 4 vuotta sitten
vanhempi
commit
d7f56c3f00

+ 2 - 0
cli/include/batchioman.h

@@ -68,6 +68,8 @@ private:
 	std::string printListdata(Json::Value root);
 	std::string printHead(Json::Value root);
 	std::string printDeletefile(Json::Value root);
+	std::string printQueue(Json::Value root);
+	std::string printDequeue(Json::Value root);
 	std::string printDeleteme(Json::Value root);
 	std::string printKeyfile(Json::Value root);
 	std::string printClosekey(Json::Value root);

+ 6 - 0
cli/include/cmdman.h

@@ -135,6 +135,10 @@ private:
 	const string descDeleteme = "delete the user you are currently logged in as "
 	                            "(needs to be confirmed with the password)";
 	CmdRet cmdDeleteme(vector<string> args);
+	const string descQueue = "add a file that is already on the server to the queue for sending with the covert channel";
+	CmdRet cmdQueue(vector<string> args);
+	const string descDequeue = "remove a file from the queue for sending with the covert channel";
+	CmdRet cmdDequeue(vector<string> args);
 
 	/**
 	 * Method prototypes for commands used internally
@@ -163,6 +167,8 @@ private:
 	CmdRet handleHead(Json::Value);
 	CmdRet handleDeletefile(Json::Value);
 	CmdRet handleDeleteme(Json::Value);
+	CmdRet handleQueue(Json::Value);
+	CmdRet handleDequeue(Json::Value);
 	CmdRet handleNotifications(Json::Value);
 };
 

+ 2 - 0
cli/include/userioman.h

@@ -51,6 +51,8 @@ private:
 	void printListdata(Json::Value root);
 	void printHead(Json::Value root);
 	void printDeletefile(Json::Value root);
+	void printQueue(Json::Value root);
+	void printDequeue(Json::Value root);
 	void printDeleteme(Json::Value root);
 	void printKeyfile(Json::Value root);
 	void printClosekey(Json::Value root);

+ 16 - 0
cli/src/batchioman.cpp

@@ -27,6 +27,8 @@ BatchIoMan::BatchIoMan(bool usessl, bool beverbose, std::string batchpath) : IoM
 	printmap["head"] = &BatchIoMan::printHead;
 	printmap["deletefile"] = &BatchIoMan::printDeletefile;
 	printmap["deleteme"] = &BatchIoMan::printDeleteme;
+	printmap["queue"] = &BatchIoMan::printQueue;
+	printmap["dequeue"] = &BatchIoMan::printDequeue;
 	printmap["keyfile"] = &BatchIoMan::printKeyfile;
 	printmap["closekey"] = &BatchIoMan::printClosekey;
 
@@ -414,6 +416,20 @@ std::string BatchIoMan::printClosekey(Json::Value root) {
 		return "Key closed.";
 }
 
+std::string BatchIoMan::printQueue(Json::Value root) {
+	if (!root["accept"].asBool())
+		return std::string("Queueing of file ") + root["file"].asString() + " failed. " + root["error"].asString();
+	else
+		return std::string("File ") + root["file"].asString() + " queued succesfully";
+}
+
+std::string BatchIoMan::printDequeue(Json::Value root) {
+	if (!root["accept"].asBool())
+		return std::string("Dequeueing of file ") + root["file"].asString() + " failed. " + root["error"].asString();
+	else
+		return std::string("File ") + root["file"].asString() + " dequeued succesfully";
+}
+
 std::string BatchIoMan::printNotifications(Json::Value root) {
 	std::string ret;
 	if (!root["accept"].asBool()) {

+ 70 - 0
cli/src/cmdman.cpp

@@ -34,6 +34,8 @@ CmdMan::CmdMan(FileMan &fm, void (*dpf)(string)) : fileman(fm) {
 	execmap["deleteme"] = &CmdMan::cmdDeleteme;
 	execmap["keyfile"] = &CmdMan::cmdKeyfile;
 	execmap["closekey"] = &CmdMan::cmdClosekey;
+	execmap["queue"] = &CmdMan::cmdQueue;
+	execmap["dequeue"] = &CmdMan::cmdDequeue;
 	execmap["notifications"] = &CmdMan::cmdNotifications;
 	execmap["connect"] = &CmdMan::cmdConnect;
 	execmap["exit"] = &CmdMan::cmdExit;
@@ -52,6 +54,8 @@ CmdMan::CmdMan(FileMan &fm, void (*dpf)(string)) : fileman(fm) {
 	helpmap["deleteme"] = descDeleteme;
 	helpmap["keyfile"] = descKeyfile;
 	helpmap["closekey"] = descClosekey;
+	helpmap["queue"] = descQueue;
+	helpmap["dequeue"] = descDequeue;
 	helpmap["notifications"] = descNotifications;
 	helpmap["connect"] = descConnect;
 	helpmap["exit"] = descExit;
@@ -71,6 +75,8 @@ CmdMan::CmdMan(FileMan &fm, void (*dpf)(string)) : fileman(fm) {
 	handlemap["head"] = &CmdMan::handleHead;
 	handlemap["deletefile"] = &CmdMan::handleDeletefile;
 	handlemap["deleteme"] = &CmdMan::handleDeleteme;
+	handlemap["queue"] = &CmdMan::handleQueue;
+	handlemap["dequeue"] = &CmdMan::handleDequeue;
 	handlemap["notifications"] = &CmdMan::handleNotifications;
 
 	debugprintfunc = dpf;
@@ -546,6 +552,44 @@ CmdMan::CmdRet CmdMan::cmdSignup(vector<string> args) {
 	return retval;
 }
 
+CmdMan::CmdRet CmdMan::cmdQueue(vector<string> args) {
+	CmdRet retval;
+	DEBUGPRINT(string(__PRETTY_FUNCTION__) + " begin");
+	Json::Value root;
+	root["command"] = "queue";
+
+	if (args.size() < 1) {
+		retval.type = error;
+		root["accept"] = false;
+		root["error"] = "not enough arguments, at least 1 argument required";
+	} else {
+		root["file"] = args[0];
+		retval.type = send;
+	}
+	retval.msg = root;
+
+	return retval;
+}
+
+CmdMan::CmdRet CmdMan::cmdDequeue(vector<string> args) {
+	CmdRet retval;
+	DEBUGPRINT(string(__PRETTY_FUNCTION__) + " begin");
+	Json::Value root;
+	root["command"] = "dequeue";
+
+	if (args.size() < 1) {
+		retval.type = error;
+		root["accept"] = false;
+		root["error"] = "not enough arguments, at least 1 argument required";
+	} else {
+		root["file"] = args[0];
+		retval.type = send;
+	}
+	retval.msg = root;
+
+	return retval;
+}
+
 /* internal commands */
 CmdMan::CmdRet CmdMan::cmdVersion(vector<string> args) {
 	CmdRet retval;
@@ -979,6 +1023,32 @@ CmdMan::CmdRet CmdMan::handleDeleteme(Json::Value root) {
 	return retval;
 }
 
+CmdMan::CmdRet CmdMan::handleQueue(Json::Value root) {
+	CmdRet retval;
+	DEBUGPRINT(string(__PRETTY_FUNCTION__) + " begin");
+
+	if (root["accept"].asBool()) {
+		retval.type = print;
+	} else {
+		retval.type = error;
+	}
+	retval.msg = root;
+	return retval;
+}
+
+CmdMan::CmdRet CmdMan::handleDequeue(Json::Value root) {
+	CmdRet retval;
+	DEBUGPRINT(string(__PRETTY_FUNCTION__) + " begin");
+
+	if (root["accept"].asBool()) {
+		retval.type = print;
+	} else {
+		retval.type = error;
+	}
+	retval.msg = root;
+	return retval;
+}
+
 CmdMan::CmdRet CmdMan::handleNotifications(Json::Value root) {
 	CmdRet retval;
 	DEBUGPRINT(string(__PRETTY_FUNCTION__) + " begin");

+ 16 - 0
cli/src/userioman.cpp

@@ -28,6 +28,8 @@ UserIoMan::UserIoMan(bool usessl, bool beverbose) : IoMan(usessl) {
 	printmap["head"] = &UserIoMan::printHead;
 	printmap["deletefile"] = &UserIoMan::printDeletefile;
 	printmap["deleteme"] = &UserIoMan::printDeleteme;
+	printmap["queue"] = &UserIoMan::printQueue;
+	printmap["dequeue"] = &UserIoMan::printDequeue;
 	printmap["keyfile"] = &UserIoMan::printKeyfile;
 	printmap["closekey"] = &UserIoMan::printClosekey;
 	printmap["notifications"] = &UserIoMan::printNotifications;
@@ -211,6 +213,20 @@ void UserIoMan::printClosekey(Json::Value root) {
 		std::cout << "Key closed." << std::endl;
 }
 
+void UserIoMan::printQueue(Json::Value root) {
+	if (!root["accept"].asBool())
+		std::cout << "Queueing of file " << root["file"] << " failed. " << root["error"].asString() << std::endl;
+	else
+		std::cout << "File " << root["file"] << " queued succesfully" << std::endl;
+}
+
+void UserIoMan::printDequeue(Json::Value root) {
+	if (!root["accept"].asBool())
+		std::cout << "Dequeueing of file " << root["file"] << " failed. " << root["error"].asString() << std::endl;
+	else
+		std::cout << "File " << root["file"] << " dequeued succesfully" << std::endl;
+}
+
 void UserIoMan::printNotifications(Json::Value root) {
 	if (!root["accept"].asBool()) {
 		std::cout << "Failed to get notifications: " << root["error"].asString() << std::endl;

+ 193 - 0
cli/test/cmdman_test.cpp

@@ -2452,6 +2452,199 @@ TEST(testNotifications, Negative) {
 	EXPECT_TRUE(cm.isLoggedIn());
 }
 
+/* =====================================
+ * tests for queue and dequeue
+ */
+TEST(testQueue, TooFewArgs) {
+	FileManMock fm;
+	CmdManForTest cm(fm, dummyDebugPrint);
+	cm.initLoggedIn();
+
+	std::string cmd;
+	std::vector<std::string> args;
+	CmdMan::CmdRet retvalCmd;
+
+	// prepare cmd/args
+	cmd = "queue";
+	args = {};
+
+	// stick into cmdman
+	retvalCmd = cm.execute(cmd, args);
+
+	// check things
+	EXPECT_EQ(retvalCmd.type, CmdMan::error);
+	EXPECT_EQ(retvalCmd.msg["command"].asString(), "queue");
+	EXPECT_FALSE(retvalCmd.msg["accept"].asBool());
+	EXPECT_NE(retvalCmd.msg["error"].asString(), "");
+
+	EXPECT_TRUE(cm.isLoggedIn());
+}
+
+TEST(testQueue, Positive) {
+	FileManMock fm;
+	CmdManForTest cm(fm, dummyDebugPrint);
+	cm.initLoggedIn();
+
+	std::string cmd;
+	std::vector<std::string> args;
+	Json::Value root;
+	CmdMan::CmdRet retvalCmd;
+	CmdMan::CmdRet retvalHdl;
+
+	// prepare cmd/args/root
+	cmd = "queue";
+	args = {"fancy_file.txt"};
+	root["command"] = "queue";
+	root["file"] = "fancy_file.txt";
+	root["accept"] = true;
+
+	// stick into cmdman
+	retvalCmd = cm.execute(cmd, args);
+	retvalHdl = cm.handle(root);
+
+	// check things
+	EXPECT_EQ(retvalCmd.type, CmdMan::send);
+	EXPECT_EQ(retvalCmd.msg["command"].asString(), "queue");
+	EXPECT_EQ(retvalCmd.msg["file"].asString(), "fancy_file.txt");
+	EXPECT_EQ(retvalHdl.type, CmdMan::print);
+	EXPECT_EQ(retvalHdl.msg["command"].asString(), "queue");
+	EXPECT_TRUE(retvalHdl.msg["accept"].asBool());
+	EXPECT_EQ(retvalHdl.msg["file"].asString(), "fancy_file.txt");
+
+	EXPECT_TRUE(cm.isLoggedIn());
+}
+
+TEST(testQueue, Negative) {
+	FileManMock fm;
+	CmdManForTest cm(fm, dummyDebugPrint);
+	cm.initLoggedIn();
+
+	std::string cmd;
+	std::vector<std::string> args;
+	Json::Value root;
+	CmdMan::CmdRet retvalCmd;
+	CmdMan::CmdRet retvalHdl;
+
+	// prepare cmd/args/root
+	cmd = "queue";
+	args = {"fancy_file.txt"};
+	root["command"] = "queue";
+	root["file"] = "fancy_file.txt";
+	root["accept"] = false;
+	root["error"] = "file does not exist";
+
+	// stick into cmdman
+	retvalCmd = cm.execute(cmd, args);
+	retvalHdl = cm.handle(root);
+
+	// check things
+	EXPECT_EQ(retvalCmd.type, CmdMan::send);
+	EXPECT_EQ(retvalCmd.msg["command"].asString(), "queue");
+	EXPECT_EQ(retvalCmd.msg["file"].asString(), "fancy_file.txt");
+	EXPECT_EQ(retvalHdl.type, CmdMan::error);
+	EXPECT_EQ(retvalHdl.msg["command"].asString(), "queue");
+	EXPECT_FALSE(retvalHdl.msg["accept"].asBool());
+	EXPECT_EQ(retvalHdl.msg["file"].asString(), "fancy_file.txt");
+	EXPECT_THAT(retvalHdl.msg["error"].asString(), testing::HasSubstr("file does not exist"));
+
+	EXPECT_TRUE(cm.isLoggedIn());
+}
+
+TEST(testDequeue, TooFewArgs) {
+	FileManMock fm;
+	CmdManForTest cm(fm, dummyDebugPrint);
+	cm.initLoggedIn();
+
+	std::string cmd;
+	std::vector<std::string> args;
+	CmdMan::CmdRet retvalCmd;
+
+	// prepare cmd/args
+	cmd = "dequeue";
+	args = {};
+
+	// stick into cmdman
+	retvalCmd = cm.execute(cmd, args);
+
+	// check things
+	EXPECT_EQ(retvalCmd.type, CmdMan::error);
+	EXPECT_EQ(retvalCmd.msg["command"].asString(), "dequeue");
+	EXPECT_FALSE(retvalCmd.msg["accept"].asBool());
+	EXPECT_NE(retvalCmd.msg["error"].asString(), "");
+
+	EXPECT_TRUE(cm.isLoggedIn());
+}
+
+TEST(testDequeue, Positive) {
+	FileManMock fm;
+	CmdManForTest cm(fm, dummyDebugPrint);
+	cm.initLoggedIn();
+
+	std::string cmd;
+	std::vector<std::string> args;
+	Json::Value root;
+	CmdMan::CmdRet retvalCmd;
+	CmdMan::CmdRet retvalHdl;
+
+	// prepare cmd/args/root
+	cmd = "dequeue";
+	args = {"fancy_file.txt"};
+	root["command"] = "dequeue";
+	root["file"] = "fancy_file.txt";
+	root["accept"] = true;
+
+	// stick into cmdman
+	retvalCmd = cm.execute(cmd, args);
+	retvalHdl = cm.handle(root);
+
+	// check things
+	EXPECT_EQ(retvalCmd.type, CmdMan::send);
+	EXPECT_EQ(retvalCmd.msg["command"].asString(), "dequeue");
+	EXPECT_EQ(retvalCmd.msg["file"].asString(), "fancy_file.txt");
+	EXPECT_EQ(retvalHdl.type, CmdMan::print);
+	EXPECT_EQ(retvalHdl.msg["command"].asString(), "dequeue");
+	EXPECT_TRUE(retvalHdl.msg["accept"].asBool());
+	EXPECT_EQ(retvalHdl.msg["file"].asString(), "fancy_file.txt");
+
+	EXPECT_TRUE(cm.isLoggedIn());
+}
+
+TEST(testDequeue, Negative) {
+	FileManMock fm;
+	CmdManForTest cm(fm, dummyDebugPrint);
+	cm.initLoggedIn();
+
+	std::string cmd;
+	std::vector<std::string> args;
+	Json::Value root;
+	CmdMan::CmdRet retvalCmd;
+	CmdMan::CmdRet retvalHdl;
+
+	// prepare cmd/args/root
+	cmd = "dequeue";
+	args = {"fancy_file.txt"};
+	root["command"] = "dequeue";
+	root["file"] = "fancy_file.txt";
+	root["accept"] = false;
+	root["error"] = "file not in queue";
+
+	// stick into cmdman
+	retvalCmd = cm.execute(cmd, args);
+	retvalHdl = cm.handle(root);
+
+	// check things
+	EXPECT_EQ(retvalCmd.type, CmdMan::send);
+	EXPECT_EQ(retvalCmd.msg["command"].asString(), "dequeue");
+	EXPECT_EQ(retvalCmd.msg["file"].asString(), "fancy_file.txt");
+	EXPECT_EQ(retvalHdl.type, CmdMan::error);
+	EXPECT_EQ(retvalHdl.msg["command"].asString(), "dequeue");
+	EXPECT_FALSE(retvalHdl.msg["accept"].asBool());
+	EXPECT_EQ(retvalHdl.msg["file"].asString(), "fancy_file.txt");
+	EXPECT_THAT(retvalHdl.msg["error"].asString(), testing::HasSubstr("file not in queue"));
+
+	EXPECT_TRUE(cm.isLoggedIn());
+}
+
 /* =====================================
  * test for all commands that require a login
  */