#include #include #include "../include/climanager.h" #include "../include/cmdmanager.h" #include "../include/config.h" #include using namespace std; namespace CmdManager { QString cachedIP; QString cachedPort; QMLHandler *qmlHandler; map cmdmap; map filemap; } // namespace CmdManager void CmdManager::init() { cmdmap["error"] = &CmdManager::handleError; cmdmap["status"] = &CmdManager::handleStatus; cmdmap["close"] = &CmdManager::handleClose; cmdmap["list"] = &CmdManager::handleList; cmdmap["extendedlist"] = &CmdManager::handleExtendedList; cmdmap["connect"] = &CmdManager::handleConnect; cmdmap["version"] = &CmdManager::handleVersion; cmdmap["login"] = &CmdManager::handleLogin; cmdmap["signup"] = &CmdManager::handleSignup; cmdmap["put"] = &CmdManager::handlePut; cmdmap["putdata"] = &CmdManager::handlePutData; cmdmap["get"] = &CmdManager::handleGet; cmdmap["getdata"] = &CmdManager::handleGetData; cmdmap["deleteme"] = &CmdManager::handleDeleteMe; cmdmap["deletefile"] = &CmdManager::handleDeleteFile; cmdmap["notifications"] = &CmdManager::handleNotifications; cmdmap["queue"] = &CmdManager::handleQueue; cmdmap["dequeue"] = &CmdManager::handleDequeue; cmdmap["extendedstatus"] = &CmdManager::handleExtendedStatus; cmdmap["keyfile"] = &CmdManager::handleKeyfile; cmdmap["closekey"] = &CmdManager::handleClosekey; cmdmap["disconnect"] = &CmdManager::handleDisconnect; cmdmap["connectionerror"] = &CmdManager::handleConnectionError; filemap.clear(); } void CmdManager::setQmlHandler(QMLHandler *q) { qmlHandler = q; } void CmdManager::updateInternalFile(string name, string type, string method, int progress, float speed) { map::iterator it = filemap.find(name); if (it != filemap.end()) { it->second.type = type; it->second.method = method; it->second.progress = progress; it->second.speed = speed; it->second.dirty = true; } } void CmdManager::emitFileList() { map::iterator it; char speedbuf[256]; string progstr; for (it = filemap.begin(); it != filemap.end(); it++) { // This is a transfer if (it->second.type.size()) { // using a covert channel if (it->second.method.size()) { snprintf(speedbuf, 256, "%.2f B/s", it->second.speed); progstr = it->second.type + " via " + it->second.method + "\n" + std::to_string(it->second.progress) + "%" + " @ " + speedbuf; } else progstr = it->second.type + "\n" + std::to_string(it->second.progress) + "%"; emit qmlHandler->serverFilesUpdateFile(it->first.c_str(), progstr.c_str(), it->second.type == "Queued" || it->second.type == "Sending"); } // else emit plain entry else emit qmlHandler->serverFilesUpdateFile(it->first.c_str(), "", false); } } void CmdManager::cleanInternalList() { map::iterator it; for (it = filemap.begin(); it != filemap.end(); it++) { if (!it->second.dirty) { it->second.type.clear(); it->second.method.clear(); it->second.progress = 0; it->second.speed = 0; } else it->second.dirty = false; } } void printInternalList() { map::iterator it; for (it = CmdManager::filemap.begin(); it != CmdManager::filemap.end(); it++) emit CmdManager::qmlHandler->log((string("IFL ENTRY ") + it->first + " " + it->second.type + " " + it->second.method + " " + std::to_string(it->second.progress) + " " + std::to_string(it->second.speed) + " " + std::to_string(it->second.dirty)) .c_str()); } void CmdManager::executeCmd(string cmd, Json::Value root) { map::iterator it = cmdmap.find(cmd); if (it == cmdmap.end()) { return; } cmdmap[cmd](root); } void CmdManager::setCachedIP(QString ip) { cachedIP = ip; } void CmdManager::setCachedPort(QString port) { cachedPort = port; } void CmdManager::handleError(Json::Value root) { emit qmlHandler->log(root["error"].asString().c_str()); } void CmdManager::handleStatus(Json::Value root) { emit qmlHandler->footerSetStatus(root["response"].asString().c_str()); } void CmdManager::handleClose(Json::Value root) { CliManager::setProgramActive(false); } void CmdManager::handleList(Json::Value root) { char sizebuf[256]; snprintf(sizebuf, 256, "%.2f", 4.2f); if (root["accept"] == true) { emit qmlHandler->serverFilesClearFileList(); filemap.clear(); // Get the array of file Names auto fileNames = root["names"]; for (int i = 0; i < fileNames.size(); i++) { emit qmlHandler->serverFilesListFile(QString::fromStdString(fileNames[i].asString()), QString::fromStdString(sizebuf), QString("Decryptable"), !!ifstream(fileNames[i].asString())); filemap[fileNames[i].asString()] = {false, "", "", 0, 0}; } } else { emit qmlHandler->log(root["error"].asString().c_str()); } } void CmdManager::handleExtendedList(Json::Value root) { char sizebuf[256]; if (root["accept"] == true) { emit qmlHandler->serverFilesClearFileList(); filemap.clear(); // Get the array of file Names auto files = root["files"]; for (Json::Value f : files) { snprintf(sizebuf, 256, "%.2f", f["size"].asFloat()); emit qmlHandler->serverFilesListFile(QString::fromStdString(f["name"].asString()), QString::fromStdString(sizebuf), QString::fromStdString(f["encrypted"].asString()), !!ifstream(f["name"].asString())); filemap[f["name"].asString()] = {false, "", "", 0, 0}; } } else { emit qmlHandler->log(root["error"].asString().c_str()); } } void CmdManager::handleConnect(Json::Value root) { if (!root["accept"].asBool()) { emit qmlHandler->ipPopupSetStatus(root["error"].asString().c_str()); emit qmlHandler->ipPopupEnableConnectButton(); } } void CmdManager::handleVersion(Json::Value root) { if (root["accept"] == true) { emit qmlHandler->ipPopupClose(); emit qmlHandler->loginSignupPopupOpen(); } else { QString errorMessage = QString::fromStdString(string("Version mismatch: \nClient: " + root["clientversion"].asString() + "\nServer: " + root["serverversion"].asString())); emit qmlHandler->ipPopupSetStatus(errorMessage); emit qmlHandler->ipPopupEnableConnectButton(); } } void CmdManager::handleLogin(Json::Value root) { if (root["accept"] == true) { emit qmlHandler->loginSignupPopupClose(); CliManager::loggedin = true; } else { QString cmd = "connect " + cachedIP + " " + cachedPort; emit qmlHandler->loginSetStatus(root["error"].asString().c_str()); CliManager::writeToCli(cmd); emit qmlHandler->loginEnableLoginButton(); } } void CmdManager::handleSignup(Json::Value root) { if (root["accept"] == true) { emit qmlHandler->loginSignupPopupClose(); CliManager::loggedin = true; } else { QString cmd = "connect " + cachedIP + " " + cachedPort; emit qmlHandler->signupSetStatus(root["error"].asString().c_str()); CliManager::writeToCli(cmd); emit qmlHandler->signupEnableRegisterButton(); } } void CmdManager::handlePut(Json::Value root) { if (root["accept"] == false) { QString errorMessage = QString::fromStdString(string("Error when uploading file " + root["file"].asString() + ":\n" + root["error"].asString())); emit qmlHandler->log(errorMessage); } } void CmdManager::handlePutData(Json::Value root) { if (root["cancel"] == true) { QString errorMessage = QString::fromStdString(string("Error when uploading file " + root["file"].asString() + ":\n" + root["error"].asString())); emit qmlHandler->log(errorMessage); } } void CmdManager::handleGet(Json::Value root) { if (root["accept"] == false) { QString errorMessage = QString::fromStdString(string("Error when downloading file " + root["file"].asString() + ":\n" + root["error"].asString())); emit qmlHandler->log(errorMessage); } else { string fileName = root["file"].asString(); emit qmlHandler->serverFilesDisableDownloadButton(QString::fromStdString(fileName)); } } void CmdManager::handleGetData(Json::Value root) { if (root["cancel"] == true) { QString errorMessage = QString::fromStdString(string("Error when downloading file " + root["file"].asString() + ":\n" + root["error"].asString())); emit qmlHandler->log(errorMessage); } } void CmdManager::handleDeleteMe(Json::Value root) { if (root["accept"] == true) { CliManager::loggedin = true; qmlHandler->setRestart(true); emit qmlHandler->closeWindow(); } else { QString errorMessage = QString::fromStdString(root["error"].asString()); emit qmlHandler->deleteMePopupSetStatus(errorMessage); } } void CmdManager::handleDeleteFile(Json::Value root) { emit qmlHandler->serverFilesCloseConfirmDeletePopup(); if (root["accept"] == false) { QString errorMessage = QString::fromStdString(string("Error when deleting file " + root["file"].asString() + ":\n" + root["error"].asString())); emit qmlHandler->log(errorMessage); } else { QString message = QString::fromStdString(string("Deleted file " + root["file"].asString() + " from the server!")); emit qmlHandler->log(message); } } void CmdManager::handleNotifications(Json::Value root) { if (root["accept"] == true) { if (!root["messages"].isNull()) { // Get the array of notifications auto notifications = root["messages"]; for (int i = 0; i < notifications.size(); i++) { emit qmlHandler->notification(QString::fromStdString(notifications[i].asString())); } if (notifications.size() > 1) emit qmlHandler->showDesktopNotification("Covert Channel - New Notifications", "You have multiple new notifications. Open the program to see them."); else if (notifications.size() == 1) emit qmlHandler->showDesktopNotification("Covert Channel - New Notification", QString::fromStdString(notifications[0].asString())); } } else { emit qmlHandler->log(root["error"].asString().c_str()); } } void CmdManager::handleQueue(Json::Value root) { if (root["accept"] == false) { QString errorMessage = QString::fromStdString(string("Error when queueing file " + root["file"].asString() + ":\n" + root["error"].asString())); emit qmlHandler->log(errorMessage); } } void CmdManager::handleDequeue(Json::Value root) { if (root["accept"] == false) { QString errorMessage = QString::fromStdString(string("Error when dequeueing file " + root["file"].asString() + ":\n" + root["error"].asString())); emit qmlHandler->log(errorMessage); } } void CmdManager::handleExtendedStatus(Json::Value root) { Json::Value cs, ss; string typestring; if (!root["accept"].asBool()) { QString errorMessage = QString::fromStdString(string("Error when loading status " + root["error"].asString())); emit qmlHandler->log(errorMessage); } else { cs = root["transfersclientserver"]; ss = root["transfersserverserver"]; if (!cs.isNull()) { for (Json::Value t : cs) { updateInternalFile(t["file"].asString(), t["upload"].asBool() ? "Upload" : "Download", "", t["progress"].asInt(), 0); } } if (!ss.isNull()) { for (Json::Value t : ss) { if (t["type"] == "download") typestring = "Receiving"; else if (t["type"] == "upload") typestring = "Sending"; else if (t["type"] == "queued") typestring = "Queued"; updateInternalFile(t["file"].asString(), typestring, t["method"].asString(), t["progress"].asInt(), t["speed"].asFloat()); } } cleanInternalList(); emitFileList(); } } void CmdManager::handleKeyfile(Json::Value root) { QString errorMessage; if (root["accept"] == false) { errorMessage = QString::fromStdString(string("Error when setting keyfile file " + root["file"].asString() + ":\n" + root["error"].asString())); emit qmlHandler->log(errorMessage); } emit qmlHandler->keyfileStatus(root["accept"].asBool(), errorMessage); } void CmdManager::handleClosekey(Json::Value root) { if (root["accept"] == false) { QString errorMessage = QString::fromStdString(string("Error when closing keyfile:\n" + root["error"].asString())); emit qmlHandler->log(errorMessage); } else { emit qmlHandler->keyfileClosedOK(); } } void CmdManager::handleDisconnect(Json::Value root) { if (root["accept"] == true) { CliManager::loggedin = false; } } void CmdManager::handleConnectionError(Json::Value root) { emit qmlHandler->footerSetError("Connection to the server lost. Use << File->Change Server... >> to connect again."); }