From 6a70501baa8a3f25cc5648f3b259772b3a618215 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E7=AD=B1=E5=82=91?= <840465812@qq.com>
Date: Sat, 12 Jan 2019 10:40:27 +0800
Subject: [PATCH] update
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
增加手动移出白名单
连续连接移出白名单
---
DaemonService.pro | 60 ++++
DaemonService.pro.user | 328 ++++++++++++++++++++
DaemonService.pro.user.2d03fc4.4.8-pre1 | 322 +++++++++++++++++++
DaemonServiceInitializer.bat | 21 ++
UAC.manifest | 10 +
daemonservice.cpp | 25 ++
daemonservice.h | 45 +++
dal.cpp | 258 ++++++++++++++++
dal.h | 41 +++
ipsechelper.cpp | 47 +++
ipsechelper.h | 25 ++
log.cpp | 14 +
log.h | 26 ++
main.cpp | 63 ++++
mainwindow.cpp | 197 ++++++++++++
mainwindow.h | 36 +++
mainwindow.ui | 178 +++++++++++
md5.cpp | 394 ++++++++++++++++++++++++
md5.h | 10 +
model.h | 26 ++
res.qrc | 5 +
uac.rc | 1 +
worker.cpp | 135 ++++++++
worker.h | 32 ++
24 files changed, 2299 insertions(+)
create mode 100644 DaemonService.pro
create mode 100644 DaemonService.pro.user
create mode 100644 DaemonService.pro.user.2d03fc4.4.8-pre1
create mode 100644 DaemonServiceInitializer.bat
create mode 100644 UAC.manifest
create mode 100644 daemonservice.cpp
create mode 100644 daemonservice.h
create mode 100644 dal.cpp
create mode 100644 dal.h
create mode 100644 ipsechelper.cpp
create mode 100644 ipsechelper.h
create mode 100644 log.cpp
create mode 100644 log.h
create mode 100644 main.cpp
create mode 100644 mainwindow.cpp
create mode 100644 mainwindow.h
create mode 100644 mainwindow.ui
create mode 100644 md5.cpp
create mode 100644 md5.h
create mode 100644 model.h
create mode 100644 res.qrc
create mode 100644 uac.rc
create mode 100644 worker.cpp
create mode 100644 worker.h
diff --git a/DaemonService.pro b/DaemonService.pro
new file mode 100644
index 0000000..9ca2324
--- /dev/null
+++ b/DaemonService.pro
@@ -0,0 +1,60 @@
+#-------------------------------------------------
+#
+# Project created by QtCreator 2018-12-27T16:26:24
+#
+#-------------------------------------------------
+
+QT += core gui network sql
+RESOURCES += res.qrc
+RC_ICONS = Daemon.ico
+
+greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
+
+TARGET = DaemonService
+TEMPLATE = app
+
+# The following define makes your compiler emit warnings if you use
+# any feature of Qt which has been marked as deprecated (the exact warnings
+# depend on your compiler). Please consult the documentation of the
+# deprecated API in order to know how to port your code away from it.
+DEFINES += QT_DEPRECATED_WARNINGS
+
+# You can also make your code fail to compile if you use deprecated APIs.
+# In order to do so, uncomment the following line.
+# You can also select to disable deprecated APIs only up to a certain version of Qt.
+#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
+
+CONFIG += c++11
+
+SOURCES += \
+ main.cpp \
+ mainwindow.cpp \
+ daemonservice.cpp \
+ worker.cpp \
+ md5.cpp \
+ dal.cpp \
+ log.cpp \
+ ipsechelper.cpp
+
+HEADERS += \
+ mainwindow.h \
+ daemonservice.h \
+ worker.h \
+ md5.h \
+ dal.h \
+ model.h \
+ log.h \
+ ipsechelper.h
+
+FORMS += \
+ mainwindow.ui
+
+RC_FILE = uac.rc
+
+# Default rules for deployment.
+qnx: target.path = /tmp/$${TARGET}/bin
+else: unix:!android: target.path = /opt/$${TARGET}/bin
+!isEmpty(target.path): INSTALLS += target
+
+RESOURCES += \
+ res.qrc
diff --git a/DaemonService.pro.user b/DaemonService.pro.user
new file mode 100644
index 0000000..b8fea51
--- /dev/null
+++ b/DaemonService.pro.user
@@ -0,0 +1,328 @@
+
+
+
+
+
+ EnvironmentId
+ {6a2adf44-d351-4499-8d66-24024cfa2d9d}
+
+
+ ProjectExplorer.Project.ActiveTarget
+ 0
+
+
+ ProjectExplorer.Project.EditorSettings
+
+ true
+ false
+ true
+
+ Cpp
+
+ CppGlobal
+
+
+
+ QmlJS
+
+ QmlJSGlobal
+
+
+ 2
+ UTF-8
+ false
+ 4
+ false
+ 80
+ true
+ true
+ 1
+ true
+ false
+ 0
+ true
+ true
+ 0
+ 8
+ true
+ 1
+ true
+ true
+ true
+ false
+
+
+
+ ProjectExplorer.Project.PluginSettings
+
+
+ -fno-delayed-template-parsing
+
+ true
+
+
+
+ ProjectExplorer.Project.Target.0
+
+ Desktop Qt 5.6.2 MinGW 32bit
+ Desktop Qt 5.6.2 MinGW 32bit
+ qt.56.win32_mingw49_kit
+ 1
+ 0
+ 0
+
+ F:/Qt/build-DaemonService-Desktop_Qt_5_6_2_MinGW_32bit-Debug
+
+
+ true
+ qmake
+
+ QtProjectManager.QMakeBuildStep
+ true
+
+ false
+ false
+ false
+
+
+ true
+ Make
+
+ Qt4ProjectManager.MakeStep
+
+ false
+
+
+ false
+
+ 2
+ Build
+
+ ProjectExplorer.BuildSteps.Build
+
+
+
+ true
+ Make
+
+ Qt4ProjectManager.MakeStep
+
+ true
+ clean
+
+ false
+
+ 1
+ Clean
+
+ ProjectExplorer.BuildSteps.Clean
+
+ 2
+ false
+
+ Debug
+ Debug
+ Qt4ProjectManager.Qt4BuildConfiguration
+ 2
+ true
+
+
+ F:/Qt/build-DaemonService-Desktop_Qt_5_6_2_MinGW_32bit-Release
+
+
+ true
+ qmake
+
+ QtProjectManager.QMakeBuildStep
+ false
+
+ false
+ false
+ false
+
+
+ true
+ Make
+
+ Qt4ProjectManager.MakeStep
+
+ false
+
+
+ false
+
+ 2
+ Build
+
+ ProjectExplorer.BuildSteps.Build
+
+
+
+ true
+ Make
+
+ Qt4ProjectManager.MakeStep
+
+ true
+ clean
+
+ false
+
+ 1
+ Clean
+
+ ProjectExplorer.BuildSteps.Clean
+
+ 2
+ false
+
+ Release
+ Release
+ Qt4ProjectManager.Qt4BuildConfiguration
+ 0
+ true
+
+
+ F:/Qt/build-DaemonService-Desktop_Qt_5_6_2_MinGW_32bit-Profile
+
+
+ true
+ qmake
+
+ QtProjectManager.QMakeBuildStep
+ true
+
+ false
+ true
+ false
+
+
+ true
+ Make
+
+ Qt4ProjectManager.MakeStep
+
+ false
+
+
+ false
+
+ 2
+ Build
+
+ ProjectExplorer.BuildSteps.Build
+
+
+
+ true
+ Make
+
+ Qt4ProjectManager.MakeStep
+
+ true
+ clean
+
+ false
+
+ 1
+ Clean
+
+ ProjectExplorer.BuildSteps.Clean
+
+ 2
+ false
+
+ Profile
+ Profile
+ Qt4ProjectManager.Qt4BuildConfiguration
+ 0
+ true
+
+ 3
+
+
+ 0
+ 部署
+
+ ProjectExplorer.BuildSteps.Deploy
+
+ 1
+ Deploy Configuration
+
+ ProjectExplorer.DefaultDeployConfiguration
+
+ 1
+
+
+ false
+ false
+ 1000
+
+ true
+
+ false
+ false
+ false
+ false
+ true
+ 0.01
+ 10
+ true
+ 1
+ 25
+
+ 1
+ true
+ false
+ true
+ valgrind
+
+ 0
+ 1
+ 2
+ 3
+ 4
+ 5
+ 6
+ 7
+ 8
+ 9
+ 10
+ 11
+ 12
+ 13
+ 14
+
+ 2
+
+ DaemonService
+
+ Qt4ProjectManager.Qt4RunConfiguration:F:/Qt/DaemonService/DaemonService.pro
+ DaemonService.pro
+
+ 3768
+ false
+ true
+ true
+ false
+ false
+ true
+
+ F:/Qt/build-DaemonService-Desktop_Qt_5_6_2_MinGW_32bit-Release
+
+ 1
+
+
+
+ ProjectExplorer.Project.TargetCount
+ 1
+
+
+ ProjectExplorer.Project.Updater.FileVersion
+ 20
+
+
+ Version
+ 20
+
+
diff --git a/DaemonService.pro.user.2d03fc4.4.8-pre1 b/DaemonService.pro.user.2d03fc4.4.8-pre1
new file mode 100644
index 0000000..0451085
--- /dev/null
+++ b/DaemonService.pro.user.2d03fc4.4.8-pre1
@@ -0,0 +1,322 @@
+
+
+
+
+
+ EnvironmentId
+ {2d03fc4c-541a-4fa5-8f5c-ae92a1998dce}
+
+
+ ProjectExplorer.Project.ActiveTarget
+ 0
+
+
+ ProjectExplorer.Project.EditorSettings
+
+ true
+ false
+ true
+
+ Cpp
+
+ CppGlobal
+
+
+
+ QmlJS
+
+ QmlJSGlobal
+
+
+ 2
+ UTF-8
+ false
+ 4
+ false
+ 80
+ true
+ true
+ 1
+ true
+ false
+ 0
+ true
+ true
+ 0
+ 8
+ true
+ 1
+ true
+ true
+ true
+ false
+
+
+
+ ProjectExplorer.Project.PluginSettings
+
+
+ -fno-delayed-template-parsing
+
+ true
+
+
+
+ ProjectExplorer.Project.Target.0
+
+ Desktop Qt 5.11.2 MinGW 32bit
+ Desktop Qt 5.11.2 MinGW 32bit
+ qt.qt5.5112.win32_mingw53_kit
+ 0
+ 0
+ 0
+
+ E:/C++/Qt/build-DaemonService-Desktop_Qt_5_11_2_MinGW_32bit-Debug
+
+
+ true
+ qmake
+
+ QtProjectManager.QMakeBuildStep
+ true
+
+ false
+ false
+ false
+
+
+ true
+ Make
+
+ Qt4ProjectManager.MakeStep
+
+ false
+
+
+
+ 2
+ Build
+
+ ProjectExplorer.BuildSteps.Build
+
+
+
+ true
+ Make
+
+ Qt4ProjectManager.MakeStep
+
+ true
+ clean
+
+
+ 1
+ Clean
+
+ ProjectExplorer.BuildSteps.Clean
+
+ 2
+ false
+
+ Debug
+ Debug
+ Qt4ProjectManager.Qt4BuildConfiguration
+ 2
+ true
+
+
+ E:/C++/Qt/build-DaemonService-Desktop_Qt_5_11_2_MinGW_32bit-Release
+
+
+ true
+ qmake
+
+ QtProjectManager.QMakeBuildStep
+ false
+
+ false
+ false
+ true
+
+
+ true
+ Make
+
+ Qt4ProjectManager.MakeStep
+
+ false
+
+
+
+ 2
+ Build
+
+ ProjectExplorer.BuildSteps.Build
+
+
+
+ true
+ Make
+
+ Qt4ProjectManager.MakeStep
+
+ true
+ clean
+
+
+ 1
+ Clean
+
+ ProjectExplorer.BuildSteps.Clean
+
+ 2
+ false
+
+ Release
+ Release
+ Qt4ProjectManager.Qt4BuildConfiguration
+ 0
+ true
+
+
+ E:/C++/Qt/build-DaemonService-Desktop_Qt_5_11_2_MinGW_32bit-Profile
+
+
+ true
+ qmake
+
+ QtProjectManager.QMakeBuildStep
+ true
+
+ false
+ true
+ true
+
+
+ true
+ Make
+
+ Qt4ProjectManager.MakeStep
+
+ false
+
+
+
+ 2
+ Build
+
+ ProjectExplorer.BuildSteps.Build
+
+
+
+ true
+ Make
+
+ Qt4ProjectManager.MakeStep
+
+ true
+ clean
+
+
+ 1
+ Clean
+
+ ProjectExplorer.BuildSteps.Clean
+
+ 2
+ false
+
+ Profile
+ Profile
+ Qt4ProjectManager.Qt4BuildConfiguration
+ 0
+ true
+
+ 3
+
+
+ 0
+ 部署
+
+ ProjectExplorer.BuildSteps.Deploy
+
+ 1
+ Deploy Configuration
+
+ ProjectExplorer.DefaultDeployConfiguration
+
+ 1
+
+
+ false
+ false
+ 1000
+
+ true
+
+ false
+ false
+ false
+ false
+ true
+ 0.01
+ 10
+ true
+ 1
+ 25
+
+ 1
+ true
+ false
+ true
+ valgrind
+
+ 0
+ 1
+ 2
+ 3
+ 4
+ 5
+ 6
+ 7
+ 8
+ 9
+ 10
+ 11
+ 12
+ 13
+ 14
+
+ 2
+
+ DaemonService
+
+ Qt4ProjectManager.Qt4RunConfiguration:E:/C++/Qt/DaemonService/DaemonService.pro
+ true
+
+ DaemonService.pro
+
+ E:/C++/Qt/build-DaemonService-Desktop_Qt_5_11_2_MinGW_32bit-Debug
+ 3768
+ false
+ true
+ false
+ false
+ true
+
+ 1
+
+
+
+ ProjectExplorer.Project.TargetCount
+ 1
+
+
+ ProjectExplorer.Project.Updater.FileVersion
+ 18
+
+
+ Version
+ 18
+
+
diff --git a/DaemonServiceInitializer.bat b/DaemonServiceInitializer.bat
new file mode 100644
index 0000000..6c8a73e
--- /dev/null
+++ b/DaemonServiceInitializer.bat
@@ -0,0 +1,21 @@
+@echo off
+echo Daemon Service Initialize Start...
+
+netsh ipsec static add policy name=DaemonService
+netsh ipsec static add filterlist name=whitelist
+netsh ipsec static add filterlist name=blacklist
+netsh ipsec static add filter filterlist=whitelist srcaddr=192.169.0.100 dstaddr=me protocol=ICMP
+netsh ipsec static add filter filterlist=blacklist srcaddr=192.169.0.100 dstaddr=me protocol=ICMP
+netsh ipsec static add filteraction name=permit action=permit
+netsh ipsec static add filteraction name=block action=block
+netsh ipsec static add rule name=permitRule policy=DaemonService filterlist=whitelist filteraction=permit
+netsh ipsec static add rule name=blockRule policy=DaemonService filterlist=blacklist filteraction=block
+netsh ipsec static delete filter filterlist=whitelist srcaddr=192.169.0.100 dstaddr=me protocol=ICMP
+netsh ipsec static delete filter filterlist=blacklist srcaddr=192.169.0.100 dstaddr=me protocol=ICMP
+netsh ipsec static set policy name=DaemonService assign=y
+
+rem ֹκͨTcpָ˿ڣʹ䣬dstportijɶӦ˿
+rem netsh ipsec static add filter filterlist=blacklist srcaddr=any dstaddr=me protocol=TCP dstport=9876
+
+echo End of initialization
+pause
\ No newline at end of file
diff --git a/UAC.manifest b/UAC.manifest
new file mode 100644
index 0000000..b9b1f7f
--- /dev/null
+++ b/UAC.manifest
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/daemonservice.cpp b/daemonservice.cpp
new file mode 100644
index 0000000..13cd81e
--- /dev/null
+++ b/daemonservice.cpp
@@ -0,0 +1,25 @@
+#include "daemonservice.h"
+#include
+#include
+#include
+#include
+#include "worker.h"
+
+//DaemonService::DaemonService()
+//{
+// if (this->listen(QHostAddress::AnyIPv4, 9876))
+// qDebug("The server started successfully!");
+// else
+// qCritical("Server failed to start!Error message:%s", this->errorString().toStdString().data()); //错误信息
+//}
+
+/**
+ * @brief 当有新连接进入时
+ */
+void DaemonService::incomingConnection(qintptr socketDescriptor)
+{
+ // qDebug("new connect is connect %d(有新的连接进入!)", socketDescriptor);
+ Worker *worker = new Worker(socketDescriptor, this->m_portList);
+ QThreadPool::globalInstance()->start(worker);
+}
+
diff --git a/daemonservice.h b/daemonservice.h
new file mode 100644
index 0000000..976661c
--- /dev/null
+++ b/daemonservice.h
@@ -0,0 +1,45 @@
+#ifndef DAEMONSERVICE_H
+#define DAEMONSERVICE_H
+
+#include
+#include
+#include
+#include
+#include
+
+/**
+ * @brief 守护服务类,单例实现
+ */
+class DaemonService : public QTcpServer
+{
+ Q_OBJECT
+public:
+ /**
+ * @brief 单例对象
+ * @return 唯一对象
+ */
+ static DaemonService& instance()
+ {
+ static DaemonService obj;
+ return obj;
+ }
+
+ void setPortList(QList portList)
+ {
+ this->m_portList = portList;
+ }
+
+private:
+ explicit DaemonService() = default;
+ DaemonService(const DaemonService&) = delete;
+ DaemonService& operator=(const DaemonService&) = delete;
+protected:
+ /**
+ * @brief 当有新连接进入时
+ */
+ virtual void incomingConnection(qintptr socketDescriptor);
+private:
+ QList m_portList;
+};
+
+#endif // DAEMONSERVICE_H
diff --git a/dal.cpp b/dal.cpp
new file mode 100644
index 0000000..b5ff252
--- /dev/null
+++ b/dal.cpp
@@ -0,0 +1,258 @@
+#include "dal.h"
+#include
+#include
+#include
+#include
+#include
+#include "model.h"
+
+bool DAL::updateWhiteList(QString ip, QList portList)
+{
+ if (portList.empty())
+ return false;
+ // 先找找看指定项存不存在
+ QString sql = QString("SELECT * FROM whitelist WHERE IP=? AND Port in (%1").arg(portList[0]);
+ for (int i = 1; i < portList.size(); ++i)
+ sql += QString(",%1").arg(portList[i]);
+ sql += ");";
+ QSqlQuery query;
+ query.prepare(sql);
+ query.addBindValue(ip);
+ if(!query.exec())
+ {
+ qCritical()< whitelist;
+ while(query.next())
+ whitelist.append(WhiteListItem(query.value(0).toInt(), query.value(1).toString(), query.value(2).toInt(), query.value(3).toDateTime()));
+
+ // 开始事务
+ QSqlDatabase database = QSqlDatabase::database(QSqlDatabase::defaultConnection);
+ database.transaction();
+
+ // 检查数据库中的白名单
+ for (int i = 0; i < whitelist.size(); ++i)
+ {
+ // 如果要更新的已经存在,则update
+ if (portList.contains(whitelist[i].Port))
+ {
+ query.prepare("UPDATE whitelist SET LastUpdateTime = datetime(CURRENT_TIMESTAMP,'localtime') WHERE IP=? AND Port=?");
+ query.addBindValue(ip);
+ query.addBindValue(whitelist[i].Port);
+ if(!query.exec())
+ {
+ qCritical()< DAL::getWhiteList(QString ip)
+{
+ QList whitelist;
+
+ QString sql = QString("SELECT * FROM whitelist WHERE IP=?");
+ QSqlQuery query;
+ query.prepare(sql);
+ query.addBindValue(ip);
+ if(!query.exec())
+ {
+ qCritical()< ports)
+{
+ QString portStr = QString("%1").arg(ports[0]);
+ for (int i = 0; i < ports.length(); ++i)
+ portStr += QString(",%1").arg(ports[i]);
+ QString sql = QString("DELETE FROM whitelist WHERE IP=? AND Port in (%1)").arg(portStr);
+ QSqlQuery query;
+ query.prepare(sql);
+ query.addBindValue(ip);
+ if(!query.exec())
+ qCritical()<
+#include
+#include "model.h"
+
+class DAL
+{
+public:
+ static DAL &instance()
+ {
+ static DAL obj;
+ return obj;
+ }
+
+ bool updateWhiteList(int id, QDateTime lastUpdateTime);
+ /**
+ * @brief 更新白名单用户
+ * @param ip地址
+ * @param 端口列表
+ * @return 是否成功
+ */
+ bool updateWhiteList(QString ip, QList portList);
+
+ QList getWhiteList(QString ip);
+ void removeFromWhiteList(QString ip, QList ports);
+
+ 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();
+};
+
+#endif // DAL_H
diff --git a/ipsechelper.cpp b/ipsechelper.cpp
new file mode 100644
index 0000000..0261eb0
--- /dev/null
+++ b/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/ipsechelper.h b/ipsechelper.h
new file mode 100644
index 0000000..bb3722b
--- /dev/null
+++ b/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/log.cpp b/log.cpp
new file mode 100644
index 0000000..1d04e98
--- /dev/null
+++ b/log.cpp
@@ -0,0 +1,14 @@
+#include
+#include
+#include "log.h"
+
+void Log::append(QString msg)
+{
+ //保存输出相关信息到指定文件
+ QFile outputFile("DaemonServiceLog.txt");
+ outputFile.open(QIODevice::WriteOnly | QIODevice::Append);
+ QTextStream textStream(&outputFile);
+ textStream << msg << endl;
+
+ emit appendEvent(msg);
+}
diff --git a/log.h b/log.h
new file mode 100644
index 0000000..91a1848
--- /dev/null
+++ b/log.h
@@ -0,0 +1,26 @@
+#ifndef LOG_H
+#define LOG_H
+
+#include
+
+class Log : public QObject
+{
+ Q_OBJECT
+public:
+ static Log& instance()
+ {
+ static Log obj;
+ return obj;
+ }
+ void append(QString msg);
+signals:
+ void appendEvent(QString msg);
+
+private:
+ explicit Log(QObject *parent = nullptr)
+ : QObject(parent) { }
+ Log(const Log&) = delete;
+ Log& operator=(const Log&) = delete;
+};
+
+#endif // LOG_H
diff --git a/main.cpp b/main.cpp
new file mode 100644
index 0000000..b256d9a
--- /dev/null
+++ b/main.cpp
@@ -0,0 +1,63 @@
+#include "mainwindow.h"
+#include
+#include
+#include
+#include
+#include
+#include
+#include "daemonservice.h"
+#include "log.h"
+
+void customMessageHandler(QtMsgType type, const QMessageLogContext &, const QString & str);
+
+int main(int argc, char *argv[])
+{
+ QApplication a(argc, argv);
+ // 使用共享内存,防止程序重复启动
+ QSharedMemory singleton(a.applicationName());
+ if(!singleton.create(1))
+ {
+ QMessageBox::warning(nullptr, "Waring", "Program already running!(服务已经启动,请不要重复启动服务)");
+ return 1;
+ }
+
+ //注册MsgHandler回调函数
+ qInstallMessageHandler(customMessageHandler);
+
+ MainWindow w;
+ w.show();
+ return a.exec();
+}
+
+// 日志
+void customMessageHandler(QtMsgType type, const QMessageLogContext &, const QString & str)
+{
+ QString txtMessage;
+
+ switch (type)
+ {
+ case QtDebugMsg: //调试信息提示
+ txtMessage = QString("%1 Debug(调试):\t%2").arg(QDateTime::currentDateTime().toString("yy/MM/dd HH:mm:ss")).arg(str);
+ break;
+
+ case QtWarningMsg: //一般的warning提示
+ txtMessage = QString("%1 Warning(警告):\t%2").arg(QDateTime::currentDateTime().toString("yy/MM/dd HH:mm:ss")).arg(str);
+ break;
+
+ case QtCriticalMsg: //严重错误提示
+ txtMessage = QString("%1 Critical(错误):\t%2").arg(QDateTime::currentDateTime().toString("yy/MM/dd HH:mm:ss")).arg(str);
+ break;
+
+ case QtFatalMsg: //致命错误提示
+ txtMessage = QString("%1 Fatal(致命错误):\t%2").arg(QDateTime::currentDateTime().toString("yy/MM/dd HH:mm:ss")).arg(str);
+ break;
+
+ default:
+ return;
+ }
+
+ Log::instance().append(txtMessage);
+
+ if (type == QtFatalMsg)
+ abort();
+}
diff --git a/mainwindow.cpp b/mainwindow.cpp
new file mode 100644
index 0000000..4380e1d
--- /dev/null
+++ b/mainwindow.cpp
@@ -0,0 +1,197 @@
+#include "mainwindow.h"
+#include "ui_mainwindow.h"
+#include "daemonservice.h"
+#include "log.h"
+#include
+#include
+#include "dal.h"
+#include "ipsechelper.h"
+
+MainWindow::MainWindow(QWidget *parent) :
+ QMainWindow(parent),
+ ui(new Ui::MainWindow)
+{
+ ui->setupUi(this);
+ setWindowIcon(QIcon(":/Daemon.ico"));
+ connect(&Log::instance(), &Log::appendEvent, this, &MainWindow::log_append);
+
+ ui->txtPortList->setPlainText(DAL::instance().getPortList());
+}
+
+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() == "启动服务")
+ {
+ QList portList = getInputPortList();
+ if (portList.isEmpty())
+ {
+ log_append("Please enter the port number to be guarded!(请输入要保护的端口号!)");
+ return;
+ }
+ DaemonService::instance().setPortList(portList);
+ qDebug("The service is starting up...(服务正在启动中...)");
+ // 开始监听,绑定端口为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("关闭服务");
+ }
+ else
+ {
+ qCritical() << ("Service startup failed with error message(服务启动失败,错误消息:):" + DaemonService::instance().errorString());
+ }
+ }
+ else
+ {
+ qDebug("The service is shutting down...(服务正在关闭...)");
+ DaemonService::instance().close();
+ ui->txtPortList->setReadOnly(false);
+ ui->pushButton->setText("启动服务");
+ qDebug("Service closed!(服务已关闭)");
+ }
+}
+
+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("添加失败");
+}
+
+void MainWindow::on_btnRemoveIP_clicked()
+{
+ QString ip = ui->txtIP->text();
+ if (ip.isEmpty())
+ {
+ log_append("请输入要移除白名单的IP");
+ return;
+ }
+ QList portList = getInputPortList();
+ auto list = DAL::instance().getWhiteList(ip);
+ for (int i = portList.length() - 1; i >= 0; --i)
+ {
+ bool flag = false;
+ for (const auto &item : list)
+ {
+ if (item.Port == portList[i])
+ {
+ flag = true;
+ break;
+ }
+ }
+ if (flag)
+ {
+ IpsecHelper::removeItemFromWhiteList(ip, portList[i]);
+ }
+ else
+ {
+ portList.removeAt(i);
+ }
+ }
+ if (portList.length() < 1)
+ qDebug("IP:%s 不存在白名单中", ip.toStdString().data());
+ else
+ {
+ DAL::instance().removeFromWhiteList(ip, portList);
+ qDebug("IP:%s 已移出指定端口白名单", ip.toStdString().data());
+ }
+}
diff --git a/mainwindow.h b/mainwindow.h
new file mode 100644
index 0000000..6275805
--- /dev/null
+++ b/mainwindow.h
@@ -0,0 +1,36 @@
+#ifndef MAINWINDOW_H
+#define MAINWINDOW_H
+
+#include
+
+namespace Ui {
+class MainWindow;
+}
+
+class MainWindow : public QMainWindow
+{
+ Q_OBJECT
+
+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();
+
+ void on_btnRemoveIP_clicked();
+
+private:
+ Ui::MainWindow *ui;
+};
+
+#endif // MAINWINDOW_H
diff --git a/mainwindow.ui b/mainwindow.ui
new file mode 100644
index 0000000..a1f8650
--- /dev/null
+++ b/mainwindow.ui
@@ -0,0 +1,178 @@
+
+
+ MainWindow
+
+
+
+ 0
+ 0
+ 700
+ 320
+
+
+
+
+ 700
+ 320
+
+
+
+
+ 700
+ 320
+
+
+
+ DaemonService
+
+
+
+
+
+ 130
+ 30
+ 561
+ 281
+
+
+
+ <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
+<html><head><meta name="qrichtext" content="1" /><style type="text/css">
+p, li { white-space: pre-wrap; }
+</style></head><body style=" font-family:'SimSun'; font-size:9pt; font-weight:400; font-style:normal;">
+<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p></body></html>
+
+
+
+
+
+ 10
+ 30
+ 111
+ 71
+
+
+
+ 7001
+
+
+
+
+
+ 10
+ 270
+ 111
+ 41
+
+
+
+ 启动服务
+
+
+
+
+
+ 10
+ 10
+ 91
+ 16
+
+
+
+ 守护端口列表:
+
+
+
+
+
+ 130
+ 10
+ 71
+ 16
+
+
+
+ 日志信息:
+
+
+
+
+
+ 10
+ 110
+ 111
+ 31
+
+
+
+ 封锁以上端口
+
+
+
+
+
+ 650
+ 10
+ 41
+ 21
+
+
+
+ 清空
+
+
+
+
+
+ 10
+ 190
+ 111
+ 20
+
+
+
+
+
+
+ 10
+ 210
+ 51
+ 23
+
+
+
+ +
+
+
+
+
+
+ 70
+ 210
+ 51
+ 23
+
+
+
+ -
+
+
+
+
+
+ 10
+ 170
+ 54
+ 12
+
+
+
+ 白名单IP:
+
+
+
+
+
+
+
+
diff --git a/md5.cpp b/md5.cpp
new file mode 100644
index 0000000..ab7370d
--- /dev/null
+++ b/md5.cpp
@@ -0,0 +1,394 @@
+#include
+#include
+#include
+#include
+#include
+#include "md5.h"
+
+/* POINTER defines a generic pointer type */
+typedef unsigned char *POINTER;
+
+/* UINT2 defines a two byte word */
+typedef unsigned short int UINT2;
+
+/* UINT4 defines a four byte word */
+typedef unsigned long int UINT4;
+
+#define PROTO_LIST(list) list
+
+/* MD5 context. */
+typedef struct _MD5_CTX
+{
+ UINT4 state[4]; /* state (ABCD) */
+ UINT4 count[2]; /* number of bits, modulo 2^64 (lsb first) */
+ unsigned char buffer[64]; /* input buffer */
+} MD5_CTX;
+
+/* Constants for MD5Transform routine.
+*/
+#define S11 7
+#define S12 12
+#define S13 17
+#define S14 22
+#define S21 5
+#define S22 9
+#define S23 14
+#define S24 20
+#define S31 4
+#define S32 11
+#define S33 16
+#define S34 23
+#define S41 6
+#define S42 10
+#define S43 15
+#define S44 21
+
+static unsigned char PADDING[64] = {
+0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+/* F, G, H and I are basic MD5 functions.
+*/
+#define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
+#define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
+#define H(x, y, z) ((x) ^ (y) ^ (z))
+#define I(x, y, z) ((y) ^ ((x) | (~z)))
+
+/* ROTATE_LEFT rotates x left n bits.
+*/
+#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
+
+/* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
+Rotation is separate from addition to prevent recomputation.
+*/
+#define FF(a, b, c, d, x, s, ac) { (a) += F ((b), (c), (d)) + (x) + (UINT4)(ac);(a) = ROTATE_LEFT ((a), (s)); (a) += (b);}
+#define GG(a, b, c, d, x, s, ac) {(a) += G ((b), (c), (d)) + (x) + (UINT4)(ac);(a) = ROTATE_LEFT ((a), (s)); (a) += (b); }
+#define HH(a, b, c, d, x, s, ac) {(a) += H ((b), (c), (d)) + (x) + (UINT4)(ac);(a) = ROTATE_LEFT ((a), (s)); (a) += (b);}
+#define II(a, b, c, d, x, s, ac) {(a) += I ((b), (c), (d)) + (x) + (UINT4)(ac);(a) = ROTATE_LEFT ((a), (s));(a) += (b);}
+
+#define TEST_BLOCK_LEN 1000
+#define TEST_BLOCK_COUNT 1000
+
+static void MD5Transform PROTO_LIST((UINT4[4], unsigned char[64]));
+static void Encode PROTO_LIST((unsigned char *, UINT4 *, unsigned int));
+static void Decode PROTO_LIST((UINT4 *, unsigned char *, unsigned int));
+static void MD5_memcpy PROTO_LIST((POINTER, POINTER, unsigned int));
+static void MD5_memset PROTO_LIST((POINTER, int, unsigned int));
+static void MD5Init PROTO_LIST((MD5_CTX *));
+static void MD5Update PROTO_LIST((MD5_CTX *, unsigned char *, unsigned int));
+static void MD5Final PROTO_LIST((unsigned char[16], MD5_CTX *));
+static void MDTimeTrial PROTO_LIST((void));
+static void StringAddOne PROTO_LIST((char *));
+static void Encode PROTO_LIST((unsigned char *, UINT4 *, unsigned int));
+static void Decode PROTO_LIST((UINT4 *, unsigned char *, unsigned int));
+
+/* MD5 initialization. Begins an MD5 operation, writing a new context.
+*/
+static void MD5Init(MD5_CTX *context)
+{
+ context->count[0] = context->count[1] = 0;
+ /* Load magic initialization constants.
+ */
+ context->state[0] = 0x67452301;
+ context->state[1] = 0xefcdab89;
+ context->state[2] = 0x98badcfe;
+ context->state[3] = 0x10325476;
+}
+
+/* MD5 block update operation. Continues an MD5 message-digest
+operation, processing another message block, and updating the
+context.
+*/
+static void MD5Update(
+ MD5_CTX *context, /* context */
+ unsigned char *input, /* input block */
+ unsigned int inputLen /* length of input block */
+)
+{
+ unsigned int i, index, partLen;
+
+ /* Compute number of bytes mod 64 */
+ index = (unsigned int)((context->count[0] >> 3) & 0x3F);
+
+ /* Update number of bits */
+ if ((context->count[0] += ((UINT4)inputLen << 3))
+ < ((UINT4)inputLen << 3))
+ context->count[1]++;
+ context->count[1] += ((UINT4)inputLen >> 29);
+
+ partLen = 64 - index;
+
+ /* Transform as many times as possible.
+ */
+ if (inputLen >= partLen) {
+ MD5_memcpy
+ ((POINTER)&context->buffer[index], (POINTER)input, partLen);
+ MD5Transform(context->state, context->buffer);
+
+ for (i = partLen; i + 63 < inputLen; i += 64)
+ MD5Transform(context->state, &input[i]);
+
+ index = 0;
+ }
+ else
+ i = 0;
+
+ /* Buffer remaining input */
+ MD5_memcpy
+ ((POINTER)&context->buffer[index], (POINTER)&input[i],
+ inputLen - i);
+}
+
+/* MD5 finalization. Ends an MD5 message-digest operation, writing the
+the message digest and zeroizing the context.
+*/
+static void MD5Final(
+ unsigned char digest[16], /* message digest */
+ MD5_CTX *context /* context */
+)
+{
+ unsigned char bits[8];
+ unsigned int index, padLen;
+
+ /* Save number of bits */
+ Encode(bits, context->count, 8);
+
+ /* Pad out to 56 mod 64.
+ */
+ index = (unsigned int)((context->count[0] >> 3) & 0x3f);
+ padLen = (index < 56) ? (56 - index) : (120 - index);
+ MD5Update(context, PADDING, padLen);
+
+ /* Append length (before padding) */
+ MD5Update(context, bits, 8);
+
+ /* Store state in digest */
+ Encode(digest, context->state, 16);
+
+ /* Zeroize sensitive information.
+ */
+ MD5_memset((POINTER)context, 0, sizeof(*context));
+}
+
+/* MD5 basic transformation. Transforms state based on block.
+*/
+static void MD5Transform(
+ UINT4 state[4],
+ unsigned char block[64]
+)
+{
+ UINT4 a = state[0], b = state[1], c = state[2], d = state[3], x[16];
+
+ Decode(x, block, 64);
+
+ /* Round 1 */
+ FF(a, b, c, d, x[0], S11, 0xd76aa478); /* 1 */
+ FF(d, a, b, c, x[1], S12, 0xe8c7b756); /* 2 */
+ FF(c, d, a, b, x[2], S13, 0x242070db); /* 3 */
+ FF(b, c, d, a, x[3], S14, 0xc1bdceee); /* 4 */
+ FF(a, b, c, d, x[4], S11, 0xf57c0faf); /* 5 */
+ FF(d, a, b, c, x[5], S12, 0x4787c62a); /* 6 */
+ FF(c, d, a, b, x[6], S13, 0xa8304613); /* 7 */
+ FF(b, c, d, a, x[7], S14, 0xfd469501); /* 8 */
+ FF(a, b, c, d, x[8], S11, 0x698098d8); /* 9 */
+ FF(d, a, b, c, x[9], S12, 0x8b44f7af); /* 10 */
+ FF(c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */
+ FF(b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */
+ FF(a, b, c, d, x[12], S11, 0x6b901122); /* 13 */
+ FF(d, a, b, c, x[13], S12, 0xfd987193); /* 14 */
+ FF(c, d, a, b, x[14], S13, 0xa679438e); /* 15 */
+ FF(b, c, d, a, x[15], S14, 0x49b40821); /* 16 */
+
+ /* Round 2 */
+ GG(a, b, c, d, x[1], S21, 0xf61e2562); /* 17 */
+ GG(d, a, b, c, x[6], S22, 0xc040b340); /* 18 */
+ GG(c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */
+ GG(b, c, d, a, x[0], S24, 0xe9b6c7aa); /* 20 */
+ GG(a, b, c, d, x[5], S21, 0xd62f105d); /* 21 */
+ GG(d, a, b, c, x[10], S22, 0x2441453); /* 22 */
+ GG(c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */
+ GG(b, c, d, a, x[4], S24, 0xe7d3fbc8); /* 24 */
+ GG(a, b, c, d, x[9], S21, 0x21e1cde6); /* 25 */
+ GG(d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */
+ GG(c, d, a, b, x[3], S23, 0xf4d50d87); /* 27 */
+ GG(b, c, d, a, x[8], S24, 0x455a14ed); /* 28 */
+ GG(a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */
+ GG(d, a, b, c, x[2], S22, 0xfcefa3f8); /* 30 */
+ GG(c, d, a, b, x[7], S23, 0x676f02d9); /* 31 */
+ GG(b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */
+
+ /* Round 3 */
+ HH(a, b, c, d, x[5], S31, 0xfffa3942); /* 33 */
+ HH(d, a, b, c, x[8], S32, 0x8771f681); /* 34 */
+ HH(c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */
+ HH(b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */
+ HH(a, b, c, d, x[1], S31, 0xa4beea44); /* 37 */
+ HH(d, a, b, c, x[4], S32, 0x4bdecfa9); /* 38 */
+ HH(c, d, a, b, x[7], S33, 0xf6bb4b60); /* 39 */
+ HH(b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */
+ HH(a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */
+ HH(d, a, b, c, x[0], S32, 0xeaa127fa); /* 42 */
+ HH(c, d, a, b, x[3], S33, 0xd4ef3085); /* 43 */
+ HH(b, c, d, a, x[6], S34, 0x4881d05); /* 44 */
+ HH(a, b, c, d, x[9], S31, 0xd9d4d039); /* 45 */
+ HH(d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */
+ HH(c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */
+ HH(b, c, d, a, x[2], S34, 0xc4ac5665); /* 48 */
+
+ /* Round 4 */
+ II(a, b, c, d, x[0], S41, 0xf4292244); /* 49 */
+ II(d, a, b, c, x[7], S42, 0x432aff97); /* 50 */
+ II(c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */
+ II(b, c, d, a, x[5], S44, 0xfc93a039); /* 52 */
+ II(a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */
+ II(d, a, b, c, x[3], S42, 0x8f0ccc92); /* 54 */
+ II(c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */
+ II(b, c, d, a, x[1], S44, 0x85845dd1); /* 56 */
+ II(a, b, c, d, x[8], S41, 0x6fa87e4f); /* 57 */
+ II(d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */
+ II(c, d, a, b, x[6], S43, 0xa3014314); /* 59 */
+ II(b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */
+ II(a, b, c, d, x[4], S41, 0xf7537e82); /* 61 */
+ II(d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */
+ II(c, d, a, b, x[2], S43, 0x2ad7d2bb); /* 63 */
+ II(b, c, d, a, x[9], S44, 0xeb86d391); /* 64 */
+
+ state[0] += a;
+ state[1] += b;
+ state[2] += c;
+ state[3] += d;
+
+ /* Zeroize sensitive information.
+ */
+ MD5_memset((POINTER)x, 0, sizeof(x));
+}
+
+/* Encodes input (UINT4) into output (unsigned char). Assumes len is
+a multiple of 4.
+*/
+static void Encode(
+ unsigned char *output,
+ UINT4 *input,
+ unsigned int len
+)
+{
+ unsigned int i, j;
+
+ for (i = 0, j = 0; j < len; i++, j += 4) {
+ output[j] = (unsigned char)(input[i] & 0xff);
+ output[j + 1] = (unsigned char)((input[i] >> 8) & 0xff);
+ output[j + 2] = (unsigned char)((input[i] >> 16) & 0xff);
+ output[j + 3] = (unsigned char)((input[i] >> 24) & 0xff);
+ }
+}
+
+/* Decodes input (unsigned char) into output (UINT4). Assumes len is
+a multiple of 4.
+*/
+static void Decode(
+ UINT4 *output,
+ unsigned char *input,
+ unsigned int len
+)
+{
+ unsigned int i, j;
+
+ for (i = 0, j = 0; j < len; i++, j += 4)
+ output[i] = ((UINT4)input[j]) | (((UINT4)input[j + 1]) << 8) |
+ (((UINT4)input[j + 2]) << 16) | (((UINT4)input[j + 3]) << 24);
+}
+
+/* Note: Replace "for loop" with standard memcpy if possible.
+*/
+static void MD5_memcpy(
+ POINTER output,
+ POINTER input,
+ unsigned int len
+)
+{
+ unsigned int i;
+
+ for (i = 0; i < len; i++)
+ output[i] = input[i];
+}
+
+/* Note: Replace "for loop" with standard memset if possible.
+*/
+static void MD5_memset(
+ POINTER output,
+ int value,
+ unsigned int len
+)
+{
+ unsigned int i;
+
+ for (i = 0; i < len; i++)
+ ((char *)output)[i] = (char)value;
+}
+
+/* Digests a string and prints the result.
+*/
+char* MD5String(char *string, unsigned int len)
+{
+ MD5_CTX context;
+ unsigned char digest[16];
+ char output1[33];
+ static char output[33] = { "" };
+ int i;
+
+ MD5Init(&context);
+ MD5Update(&context, (unsigned char*)string, len);
+ MD5Final(digest, &context);
+
+ for (i = 0; i < 16; i++)
+ {
+ sprintf(&(output1[2 * i]), "%02x", (unsigned char)digest[i]);
+ sprintf(&(output1[2 * i + 1]), "%02x", (unsigned char)(digest[i] << 4));
+ }
+ for (i = 0; i < 32; i++)
+ {
+ output[i] = output1[i];
+ }
+ return output;
+}
+
+/* get the string add one.
+*/
+static void StringAddOne(char * orstring)
+{
+ unsigned int len;
+ int i, n;
+
+ len = strlen(orstring);
+ n = len - 1;
+ for (i = n; i >= 0; i--)
+ {
+ if (orstring[i] == '9')
+ {
+ orstring[i] = 'A';
+ break;
+ }
+ else if (orstring[i] == 'Z')
+ {
+ orstring[i] = 'a';
+ break;
+ }
+ else if (orstring[i] == 'z')
+ {
+ orstring[i] = '0';
+ continue;
+ }
+ else
+ orstring[i] += 1;
+ break;
+ }
+}
+
+/* check the md5 strings one by one,get the password.
+*/
+bool MD5Check(char *md5string, char* string, unsigned int stringlen)
+{
+ return strcmp(md5string, MD5String(string, stringlen)) == 0;
+}
diff --git a/md5.h b/md5.h
new file mode 100644
index 0000000..67ec8b5
--- /dev/null
+++ b/md5.h
@@ -0,0 +1,10 @@
+#ifndef __MD5_H_
+#define __MD5_H_
+
+
+char* MD5String( char* string ,unsigned int stringlen);
+
+
+bool MD5Check( char *md5string, char* string ,unsigned int stringlen);
+
+#endif //_MD5_H_
diff --git a/model.h b/model.h
new file mode 100644
index 0000000..5aeac4e
--- /dev/null
+++ b/model.h
@@ -0,0 +1,26 @@
+#ifndef MODEL_H
+#define MODEL_H
+#include
+#include
+
+struct BlackListItem
+{
+ BlackListItem(){}
+ BlackListItem(int id, QString ip, QDateTime time, QString remarks)
+ : ID(id), IP(ip), Time(time), Remarks(remarks) {}
+ int ID;
+ QString IP;
+ QDateTime Time;
+ QString Remarks;
+};
+struct WhiteListItem
+{
+ WhiteListItem(){}
+ WhiteListItem(int id, QString ip, int port, QDateTime time)
+ : ID(id), IP(ip), Port(port), LastUpdateTime(time) {}
+ int ID;
+ QString IP;
+ int Port;
+ QDateTime LastUpdateTime;
+};
+#endif // MODEL_H
diff --git a/res.qrc b/res.qrc
new file mode 100644
index 0000000..4e72c4f
--- /dev/null
+++ b/res.qrc
@@ -0,0 +1,5 @@
+
+
+ Daemon.ico
+
+
diff --git a/uac.rc b/uac.rc
new file mode 100644
index 0000000..686301f
--- /dev/null
+++ b/uac.rc
@@ -0,0 +1 @@
+1 24 DISCARDABLE "UAC.manifest"
\ No newline at end of file
diff --git a/worker.cpp b/worker.cpp
new file mode 100644
index 0000000..71cf41f
--- /dev/null
+++ b/worker.cpp
@@ -0,0 +1,135 @@
+#include
+#include
+#include
+#include
+#include
+#include "worker.h"
+#include "md5.h"
+#include "dal.h"
+#include "model.h"
+#include "ipsechelper.h"
+
+void Worker::run()
+{
+ if (this->m_portList.empty())
+ return;
+ this->m_socket = new QTcpSocket();
+ this->m_socket->setSocketDescriptor(this->m_socketDescriptor);
+ QString ip = m_socket->peerAddress().toString();
+ if (!this->m_socket->waitForConnected(5000))
+ {
+ qDebug("IP:%s Connect Fail(该IP连接失败)", ip.toStdString().data());
+ return;
+ }
+ // qDebug("IP:%s Connect Success, Waiting for verification...(该IP连接成功,等待发送校验信息)", ip.data());
+
+ 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());
+
+ // 校验
+// if (data.toStdString()
+// == MD5("asdfas35.v;cxv-123"
+// + MD5("xck3dy$^@1309uyrew"
+// + ip.toStdString()
+// + "ioer6719024yoiuew6f178934056").toStr()
+// + "sjavlkc907*$!@(.12i.dy1").toStr())
+ QString password = ip + "asdfas35.v;cxv-123ioer6719024yosjavlkc907*$!@(.12i.dy1iuew6f178934056xck3dy$^@1309uyrew";
+
+ if (1 // 不校验了
+ || MD5Check(const_cast(data.toStdString().data()), const_cast(password.toStdString().data()), password.toStdString().length())
+ || data.length() == password.length())
+ {
+ //qDebug("Verify successful!(校验成功!)");
+
+ auto list = DAL::instance().getWhiteList(ip);
+
+
+ // 为了防止短时间内多次连接,检查最后一次连接的时间距离现在有多久
+ // 如果不超过30秒,则将其从白名单中移除
+
+
+
+
+ for (int i = this->m_portList.length(); i >= 0; --i)
+ {
+ int port = this->m_portList[i];
+ int index;
+ for (index = 0; index < list.length(); ++index)
+ {
+ if (list[index].Port == port)
+ break;
+ }
+ if (index == list.length())
+ {
+ //qDebug("Add to whitelists...(正在将该IP添加到白名单...)");
+ IpsecHelper::addItemToWhitelist(ip, port);
+ }
+ else
+ {
+ // 如果这个IP已经在白名单了,检查时间间隔
+ // 如果时间大于当前时间,说明是被手动禁止的(当前时间+10年+禁止时间)
+ if (list[index].LastUpdateTime > QDateTime::currentDateTime())
+ {
+ // 如果倒退十年,时间还没到,说明禁止时间未结束,直接结束本次处理
+ if (list[index].LastUpdateTime.addYears(-10) > QDateTime::currentDateTime())
+ {
+ qDebug("IP:%s 已拒绝", ip.toStdString().data(), port);
+ goto end;
+ }
+ else
+ {
+ qDebug("IP:%s port:%d 恢复白名单", ip.toStdString().data(), port);
+ // 否则说明禁止时间已经结束了,可以恢复其白名单了
+ IpsecHelper::addItemToWhitelist(ip, port);
+ DAL::instance().updateWhiteList(list[index].ID, QDateTime::currentDateTime());
+ // 移除这个端口,防止下面再次更新
+ this->m_portList.removeAt(i);
+ }
+ }
+ // 否则判断上一次更新是不是在30秒内
+ // 如果是的话就将它移出白名单,并且设置禁止时间
+ else if (list[index].LastUpdateTime.addSecs(30) > QDateTime::currentDateTime())
+ {
+ qDebug("IP:%s port:%d 移出白名单", ip.toStdString().data(), port);
+ IpsecHelper::removeItemFromWhiteList(ip, port);
+ DAL::instance().updateWhiteList(list[index].ID, QDateTime::currentDateTime().addYears(10).addSecs(30));
+ this->m_portList.removeAt(i);
+ }
+
+ //qDebug("Update last login time...(检测到该IP已在白名单,更新其最后上线时间...)");
+ }
+ }
+ if (this->m_portList.length() == 0 || DAL::instance().updateWhiteList(ip, this->m_portList))
+ qDebug("IP:%s 已连接", ip.toStdString().data());
+ else
+ qWarning("Update failed!(更新失败)");
+ }
+ else
+ {
+ //qWarning("Verification failed!(校验失败!)");
+ //qWarning("正在将该IP拉黑...");
+ // 校验失败,若不是算法问题,则可能是其他人想猜密码
+ IpsecHelper::addItemToBlackList(ip, 8796);
+ DAL::instance().addItemToBlackList(ip, 8796);
+ qDebug("IP:%s 已拉黑", ip.toStdString().data());
+ }
+ }
+ else
+ {
+ //qWarning("Check timeout(超过指定时间未发送任何消息,超时!)");
+ // 这个连接连上以后不发任何消息,说明不是登录器的socket
+ // 登录器的socket会在连接后立刻发送校验数据
+ // 所以将这个IP进行记录,当这个IP累计超过一定数量次连接,则将其拉黑
+ //qWarning("正在将该IP拉黑...");
+ IpsecHelper::addItemToBlackList(ip, 8796);
+ DAL::instance().addItemToBlackList(ip, 8796);
+ qDebug("IP:%s 已拉黑", ip.toStdString().data());
+ }
+end:
+ // qDebug("Close Socket connection(关闭Socket连接)");
+ // 关闭socket连接
+ this->m_socket->close();
+ this->m_socket->deleteLater();
+}
diff --git a/worker.h b/worker.h
new file mode 100644
index 0000000..b91f3f9
--- /dev/null
+++ b/worker.h
@@ -0,0 +1,32 @@
+#ifndef WORKER_H
+#define WORKER_H
+
+#include
+#include
+#include
+
+class Worker : public QRunnable
+{
+public:
+ /**
+ * @brief 唯一构造
+ * @param socket对象
+ */
+ Worker(qintptr socketDescriptor, const QList &portList)
+ : m_socketDescriptor(socketDescriptor), m_portList(portList){}
+
+protected:
+ /**
+ * @brief 线程运行方法
+ */
+ virtual void run();
+private:
+ /**
+ * @brief socket对象
+ */
+ QTcpSocket *m_socket;
+ qintptr m_socketDescriptor;
+ QList m_portList;
+};
+
+#endif // WORKER_H