diff --git a/DaemonService/DaemonService.pro b/DaemonService/DaemonService.pro index f0f34a4..9ca2324 100644 --- a/DaemonService/DaemonService.pro +++ b/DaemonService/DaemonService.pro @@ -33,7 +33,8 @@ SOURCES += \ worker.cpp \ md5.cpp \ dal.cpp \ - log.cpp + log.cpp \ + ipsechelper.cpp HEADERS += \ mainwindow.h \ @@ -42,7 +43,8 @@ HEADERS += \ md5.h \ dal.h \ model.h \ - log.h + log.h \ + ipsechelper.h FORMS += \ mainwindow.ui diff --git a/DaemonService/DaemonService.pro.user b/DaemonService/DaemonService.pro.user index 17b1fef..bf619a6 100644 --- a/DaemonService/DaemonService.pro.user +++ b/DaemonService/DaemonService.pro.user @@ -1,6 +1,6 @@ - + EnvironmentId diff --git a/DaemonService/daemonservice.cpp b/DaemonService/daemonservice.cpp index 1598ddb..13cd81e 100644 --- a/DaemonService/daemonservice.cpp +++ b/DaemonService/daemonservice.cpp @@ -18,7 +18,7 @@ */ void DaemonService::incomingConnection(qintptr socketDescriptor) { - qDebug("new connect is connect %d(有新的连接进入!)", socketDescriptor); + // qDebug("new connect is connect %d(有新的连接进入!)", socketDescriptor); Worker *worker = new Worker(socketDescriptor, this->m_portList); QThreadPool::globalInstance()->start(worker); } diff --git a/DaemonService/dal.cpp b/DaemonService/dal.cpp index 1e53de4..0e31dcf 100644 --- a/DaemonService/dal.cpp +++ b/DaemonService/dal.cpp @@ -88,10 +88,79 @@ QList DAL::getWhiteList(QString ip) return whitelist; } +bool DAL::isExistsBlackList(int port) +{ + QSqlQuery query; + query.prepare("SELECT * FROM blacklist WHERE IP='any' AND Remarks = ?"); + query.addBindValue(port); + if(!query.exec()) + { + qCritical()< getWhiteList(QString ip); + bool isExistsBlackList(int port); + bool isExistsBlackList(QString ip); + + bool addItemToBlackList(int port); + bool addItemToBlackList(QString ip, int port); + + QString getPortList(); + void setPortList(QString portList); private: DAL(); }; diff --git a/DaemonService/ipsechelper.cpp b/DaemonService/ipsechelper.cpp new file mode 100644 index 0000000..0261eb0 --- /dev/null +++ b/DaemonService/ipsechelper.cpp @@ -0,0 +1,47 @@ +#include "ipsechelper.h" +#include +#include + +void IpsecHelper::addItemToWhitelist(QString ip, int port) +{ + ExeCmd("add", "whitelist", ip, port); +} + +void IpsecHelper::removeItemFromWhiteList(QString ip, int port) +{ + ExeCmd("delete", "whitelist", ip, port); +} + +void IpsecHelper::addItemToBlackList(QString ip, int port) +{ + ExeCmd("add", "blacklist", ip, port); +} + +void IpsecHelper::removeItemFromBlackList(QString ip, int port) +{ + ExeCmd("delete", "blacklist", ip, port); +} + +void IpsecHelper::addItemToBlackList(int port) +{ + ExeCmd("add", "blacklist", "any", port); +} + +void IpsecHelper::ExeCmd(QString cmd, QString filterlist, QString srcaddr, int port) +{ + QProcess p(nullptr); + p.start("netsh", + QStringList() << "ipsec" + << "static" + << cmd + << "filter" + << ("filterlist=" + filterlist) + << ("srcaddr=" + srcaddr) + << "dstaddr=me" + << "protocol=tcp" + << "mirrored=yes" + << QString("dstport=%1").arg(port) + ); + p.waitForStarted(); + p.waitForFinished(); +} diff --git a/DaemonService/ipsechelper.h b/DaemonService/ipsechelper.h new file mode 100644 index 0000000..bb3722b --- /dev/null +++ b/DaemonService/ipsechelper.h @@ -0,0 +1,25 @@ +#ifndef IPSECHELPER_H +#define IPSECHELPER_H + +#include + +class IpsecHelper +{ +public: + IpsecHelper() = delete; + IpsecHelper(IpsecHelper&) = delete; + IpsecHelper& operator=(const IpsecHelper&) = delete; + + + static void addItemToWhitelist(QString ip, int port); + static void removeItemFromWhiteList(QString ip, int port); + + static void addItemToBlackList(QString ip, int port); + static void removeItemFromBlackList(QString ip, int port); + + static void addItemToBlackList(int port); +private: + static void ExeCmd(QString cmd, QString filterlist, QString srcaddr, int port); +}; + +#endif // IPSECHELPER_H diff --git a/DaemonService/mainwindow.cpp b/DaemonService/mainwindow.cpp index 9614eaa..d327808 100644 --- a/DaemonService/mainwindow.cpp +++ b/DaemonService/mainwindow.cpp @@ -4,6 +4,8 @@ #include "log.h" #include #include +#include "dal.h" +#include "ipsechelper.h" MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), @@ -12,6 +14,8 @@ MainWindow::MainWindow(QWidget *parent) : ui->setupUi(this); setWindowIcon(QIcon(":/Daemon.ico")); connect(&Log::instance(), &Log::appendEvent, this, &MainWindow::log_append); + + ui->txtPortList->setPlainText(DAL::instance().getPortList()); } MainWindow::~MainWindow() @@ -19,31 +23,37 @@ MainWindow::~MainWindow() delete ui; } +QList MainWindow::getInputPortList() +{ + QList portList; + QString temp = ui->txtPortList->toPlainText().trimmed(); + if (temp.isEmpty()) + { + log_append("Please enter the port number to be guarded!(请输入要保护的端口号!)"); + return portList; + } + QTextStream ts(&temp); + int port = 0; + while (!ts.atEnd()) + { + ts >> port; + + if (port < 1 || port > 65535) + { + log_append("Illegal input detected! Please enter the correct port number!(检测到非法输入! 请输入正确的端口号!)"); + return portList; + } + + portList.append(port); + } + return portList; +} + void MainWindow::on_pushButton_clicked() { if (ui->pushButton->text() == "启动服务") { - QString temp = ui->txtPortList->toPlainText().trimmed(); - if (temp.isEmpty()) - { - log_append("Please enter the port number to be guarded!(请输入要保护的端口号!)"); - return; - } - QTextStream ts(&temp); - QList portList; - int port = 0; - while (!ts.atEnd()) - { - ts >> port; - - if (port < 1 || port > 65535) - { - log_append("Illegal input detected! Please enter the correct port number!(检测到非法输入! 请输入正确的端口号!)"); - return; - } - - portList.append(port); - } + QList portList = getInputPortList(); if (portList.isEmpty()) { log_append("Please enter the port number to be guarded!(请输入要保护的端口号!)"); @@ -54,6 +64,7 @@ void MainWindow::on_pushButton_clicked() // 开始监听,绑定端口为8796 if (DaemonService::instance().listen(QHostAddress::AnyIPv4, 8796)) { + DAL::instance().setPortList(ui->txtPortList->toPlainText()); qDebug("Service started successfully!(服务启动成功!)"); ui->txtPortList->setReadOnly(true); ui->pushButton->setText("关闭服务"); @@ -77,3 +88,71 @@ void MainWindow::log_append(QString msg) { ui->txtLog->append(msg); } + +void MainWindow::on_btnClosePort_clicked() +{ + QList portList = getInputPortList(); + if (portList.isEmpty()) + { + log_append("Please enter the port number to be closed!(请输入要拦截的端口号!)"); + return; + } + for (int port : portList) + { + qDebug("正在检查端口:%d 是否已存在拦截列表", port); + if (DAL::instance().isExistsBlackList(port)) + { + qDebug("该端口已存在拦截列表,跳过操作"); + continue; + } + else + { + qDebug("该端口不存在拦截列表,开始添加到安全策略..."); + IpsecHelper::addItemToBlackList(port); + DAL::instance().addItemToBlackList(port); + qDebug("添加完成"); + } + } +} + +void MainWindow::on_BtnClear_clicked() +{ + ui->txtLog->clear(); +} + +void MainWindow::on_btnAddIP_clicked() +{ + QString ip = ui->txtIP->text(); + if (ip.isEmpty()) + { + log_append("请输入要加入白名单的IP"); + return; + } + QList portList = getInputPortList(); + auto list = DAL::instance().getWhiteList(ip); + for (int port : portList) + { + bool flag = false; + for (const auto &item : list) + { + if (item.Port == port) + { + flag = true; + break; + } + } + if (!flag) + { + //qDebug("Add to whitelists...(正在将该IP添加到白名单...)"); + IpsecHelper::addItemToWhitelist(ip, port); + } + else + { + //qDebug("Update last login time...(检测到该IP已在白名单,更新其最后上线时间...)"); + } + } + if (DAL::instance().updateWhiteList(ip, portList)) + qDebug("IP:%s 已经添加", ip.toStdString().data()); + else + qWarning("添加失败"); +} diff --git a/DaemonService/mainwindow.h b/DaemonService/mainwindow.h index f3b24c8..fdfe206 100644 --- a/DaemonService/mainwindow.h +++ b/DaemonService/mainwindow.h @@ -15,9 +15,18 @@ public: explicit MainWindow(QWidget *parent = nullptr); ~MainWindow(); +private: + QList getInputPortList(); + private slots: void on_pushButton_clicked(); void log_append(QString msg); + void on_btnClosePort_clicked(); + + void on_BtnClear_clicked(); + + void on_btnAddIP_clicked(); + private: Ui::MainWindow *ui; }; diff --git a/DaemonService/mainwindow.ui b/DaemonService/mainwindow.ui index 12ae0bd..481c2e8 100644 --- a/DaemonService/mainwindow.ui +++ b/DaemonService/mainwindow.ui @@ -60,7 +60,7 @@ p, li { white-space: pre-wrap; } 10 - 110 + 270 111 41 @@ -95,6 +95,55 @@ p, li { white-space: pre-wrap; } 日志信息: + + + + 10 + 110 + 111 + 31 + + + + 封锁以上端口 + + + + + + 650 + 10 + 41 + 21 + + + + 清空 + + + + + + 10 + 170 + 111 + 20 + + + + + + + 10 + 190 + 111 + 23 + + + + 将IP加入白名单 + + diff --git a/DaemonService/worker.cpp b/DaemonService/worker.cpp index 2e6a4ec..07a8eae 100644 --- a/DaemonService/worker.cpp +++ b/DaemonService/worker.cpp @@ -7,6 +7,7 @@ #include "md5.h" #include "dal.h" #include "model.h" +#include "ipsechelper.h" void Worker::run() { @@ -14,20 +15,19 @@ void Worker::run() return; this->m_socket = new QTcpSocket(); this->m_socket->setSocketDescriptor(this->m_socketDescriptor); - if (!this->m_socket->waitForConnected(100000)) + QString ip = m_socket->peerAddress().toString(); + if (!this->m_socket->waitForConnected(5000)) { - qDebug("IP:%s Connect Fail(该IP连接失败)", m_socket->peerAddress().toString().toStdString().data()); + qDebug("IP:%s Connect Fail(该IP连接失败)", ip.toStdString().data()); return; } - std::string ip = m_socket->peerAddress().toString().toStdString(); - qDebug("IP:%s Connect Success, Waiting for verification...(该IP连接成功,等待发送校验信息)", ip.data()); + // qDebug("IP:%s Connect Success, Waiting for verification...(该IP连接成功,等待发送校验信息)", ip.data()); - if (this->m_socket->waitForReadyRead(3000)) + if (this->m_socket->waitForReadyRead(1000)) { QByteArray data = this->m_socket->readAll(); - qDebug("IP:%s send data:'%s' ---- Verifying password...(正在校验中...)", ip.data(), data.toStdString().data()); + // qDebug("IP:%s send data:'%s' ---- Verifying password...(正在校验中...)", ip.data(), data.toStdString().data()); - QString ip = this->m_socket->peerAddress().toString(); // 校验 // if (data.toStdString() // == MD5("asdfas35.v;cxv-123" @@ -39,7 +39,7 @@ void Worker::run() if (MD5Check(const_cast(data.toStdString().data()), const_cast(password.toStdString().data()), password.toStdString().length())) { - qDebug("Verify successful!(校验成功!)"); + //qDebug("Verify successful!(校验成功!)"); auto list = DAL::instance().getWhiteList(ip); for (int port : this->m_portList) @@ -55,50 +55,42 @@ void Worker::run() } if (!flag) { - qDebug("Add to whitelists...(正在将该IP添加到白名单...)"); - // 添加到白名单中 - QProcess p(nullptr); - p.start("netsh", - QStringList() << "ipsec" - << "static" - << "add" - << "filter" - << "filterlist=whitelist" - << ("srcaddr=" + ip) - << "dstaddr=me" - << "protocol=tcp" - << "mirrored=yes" - << QString("dstport=%1").arg(port) - ); - p.waitForStarted(); - p.waitForFinished(); + //qDebug("Add to whitelists...(正在将该IP添加到白名单...)"); + IpsecHelper::addItemToWhitelist(ip, port); } else { - qDebug("Update last login time...(检测到该IP已在白名单,更新其最后上线时间...)"); + //qDebug("Update last login time...(检测到该IP已在白名单,更新其最后上线时间...)"); } } if (DAL::instance().updateWhiteList(ip, this->m_portList)) - qDebug("Update completed!(更新完成!)"); + qDebug("IP:%s 已连接", ip.toStdString().data()); else qWarning("Update failed!(更新失败)"); } else { - qWarning("Verification failed!(校验失败!)"); + //qWarning("Verification failed!(校验失败!)"); + //qWarning("正在将该IP拉黑..."); // 校验失败,若不是算法问题,则可能是其他人想猜密码 + IpsecHelper::addItemToBlackList(ip, 8796); + DAL::instance().addItemToBlackList(ip, 8796); + qDebug("IP:%s 已拉黑", ip.toStdString().data()); } } else { - qWarning("Check timeout(超过指定时间未发送任何消息,超时!)"); + //qWarning("Check timeout(超过指定时间未发送任何消息,超时!)"); // 这个连接连上以后不发任何消息,说明不是登录器的socket // 登录器的socket会在连接后立刻发送校验数据 // 所以将这个IP进行记录,当这个IP累计超过一定数量次连接,则将其拉黑 - // TODO:拉黑 + //qWarning("正在将该IP拉黑..."); + IpsecHelper::addItemToBlackList(ip, 8796); + DAL::instance().addItemToBlackList(ip, 8796); + qDebug("IP:%s 已拉黑", ip.toStdString().data()); } - qDebug("Close Socket connection(关闭Socket连接)"); + // qDebug("Close Socket connection(关闭Socket连接)"); // 关闭socket连接 this->m_socket->close(); this->m_socket->deleteLater();