From cc1dad74dd6c0bf826e652d13914a4898a22d676 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=AD=B1=E5=82=91?= <840465812@qq.com> Date: Mon, 17 Jun 2019 22:29:09 +0800 Subject: [PATCH] Add Runtime images Update README.md Delete redundant files --- .gitignore | 5 + Daemon.ico | Bin 4286 -> 0 bytes DaemonService.pro | 60 -- DaemonService.pro.user | 568 --------------- DaemonService.pro.user.2d03fc4.4.8-pre1 | 322 --------- DaemonService/DaemonService.pro.user | 304 +++++++- .../DaemonService.pro.user.6a2adf4.20 | 656 +++++++++--------- LICENSE => DaemonService/LICENSE | 0 DaemonService/dal.cpp | 52 +- DaemonService/dal.h | 5 + DaemonService/ipsechelper.cpp | 10 +- DaemonService/ipsechelper.h | 4 +- DaemonService/main.cpp | 8 +- DaemonService/mainwindow.cpp | 87 +++ DaemonService/mainwindow.h | 6 + DaemonService/mainwindow.ui | 93 ++- DaemonService/worker.cpp | 57 +- DaemonServiceInitializer.bat | 21 - README.md | 65 +- ReadMe.png | Bin 114784 -> 0 bytes UAC.manifest | 10 - daemonservice.cpp | 25 - daemonservice.h | 45 -- dal.cpp | 281 -------- dal.h | 44 -- images/DeamonService.png | Bin 0 -> 9330 bytes ipsechelper.cpp | 53 -- ipsechelper.h | 27 - log.cpp | 14 - log.h | 26 - main.cpp | 63 -- mainwindow.cpp | 245 ------- mainwindow.h | 40 -- mainwindow.ui | 227 ------ md5.cpp | 394 ----------- md5.h | 10 - model.h | 26 - res.qrc | 5 - uac.rc | 1 - worker.cpp | 132 ---- worker.h | 32 - 41 files changed, 931 insertions(+), 3092 deletions(-) create mode 100644 .gitignore delete mode 100644 Daemon.ico delete mode 100644 DaemonService.pro delete mode 100644 DaemonService.pro.user delete mode 100644 DaemonService.pro.user.2d03fc4.4.8-pre1 rename DaemonService.pro.user.6a2adf4.20 => DaemonService/DaemonService.pro.user.6a2adf4.20 (98%) rename LICENSE => DaemonService/LICENSE (100%) delete mode 100644 DaemonServiceInitializer.bat delete mode 100644 ReadMe.png delete mode 100644 UAC.manifest delete mode 100644 daemonservice.cpp delete mode 100644 daemonservice.h delete mode 100644 dal.cpp delete mode 100644 dal.h create mode 100644 images/DeamonService.png delete mode 100644 ipsechelper.cpp delete mode 100644 ipsechelper.h delete mode 100644 log.cpp delete mode 100644 log.h delete mode 100644 main.cpp delete mode 100644 mainwindow.cpp delete mode 100644 mainwindow.h delete mode 100644 mainwindow.ui delete mode 100644 md5.cpp delete mode 100644 md5.h delete mode 100644 model.h delete mode 100644 res.qrc delete mode 100644 uac.rc delete mode 100644 worker.cpp delete mode 100644 worker.h diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..f14b74d --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +################################################################################ +# 此 .gitignore 文件已由 Microsoft(R) Visual Studio 自动创建。 +################################################################################ + +/.vs diff --git a/Daemon.ico b/Daemon.ico deleted file mode 100644 index c426844cf97a413d9c2f737e860ed680d9553661..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4286 zcmeH~&uSA<6o*f0A*D!?nT1G^nuUbo6LcZ8i!QoyA)%BmTo+fqfnE3nk{Jb|h=_Di zT=WTCiYw`&Xp+`JT)N1rloGstXU5TFCO4T$MpvEi%bh>xobQ}_@64SMDeHXow+(b(bKhVRomx}`trr%|pE5v&{ zi92|mJatU=>5G|?z<(J<@tk*~`1Fm7F7oiPf2_*sbI#mml^WiNvz{l;Z`)?ubGP#PDQlQ6Lf<#@ z#!(;m)A&6|^QVa8yHnLqoy{x$a1XGi=Nm`QIb{6xS?T7!Z<#m4bkTR3%zSJw(GuE* zy-j;d&t;y!Blvmh4_UnD(C)zB`QQAoPTsZPY9FW$GuN)q(HZNHS#U2^@p0z1Abw_E zdhJNfzdYkV12_eTF;zIBrh1<`fJAYs>TFmWA;kMh?t)u jPx>Nj7b3TNB2`r&QVvRcc3pd44peHRwiap3kOTS`6saYJ diff --git a/DaemonService.pro b/DaemonService.pro deleted file mode 100644 index 9ca2324..0000000 --- a/DaemonService.pro +++ /dev/null @@ -1,60 +0,0 @@ -#------------------------------------------------- -# -# 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 deleted file mode 100644 index d6aca7d..0000000 --- a/DaemonService.pro.user +++ /dev/null @@ -1,568 +0,0 @@ - - - - - - EnvironmentId - {2d03fc4c-541a-4fa5-8f5c-ae92a1998dce} - - - ProjectExplorer.Project.ActiveTarget - 1 - - - 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.Target.1 - - Desktop Qt 5.6.2 MinGW 32bit2 - Desktop Qt 5.6.2 MinGW 32bit2 - qt.56.win32_mingw49_kit - 1 - 0 - 0 - - E:/C++/Qt/build-DaemonService-Desktop_Qt_5_6_2_MinGW_32bit2-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_6_2_MinGW_32bit2-Release - - - true - qmake - - QtProjectManager.QMakeBuildStep - false - - 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 - - Release - Release - Qt4ProjectManager.Qt4BuildConfiguration - 0 - true - - - E:/C++/Qt/build-DaemonService-Desktop_Qt_5_6_2_MinGW_32bit2-Profile - - - true - qmake - - QtProjectManager.QMakeBuildStep - true - - false - true - false - - - 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_6_2_MinGW_32bit2-Release - 3768 - false - true - false - false - true - - 1 - - - - ProjectExplorer.Project.TargetCount - 2 - - - ProjectExplorer.Project.Updater.FileVersion - 18 - - - Version - 18 - - diff --git a/DaemonService.pro.user.2d03fc4.4.8-pre1 b/DaemonService.pro.user.2d03fc4.4.8-pre1 deleted file mode 100644 index 0451085..0000000 --- a/DaemonService.pro.user.2d03fc4.4.8-pre1 +++ /dev/null @@ -1,322 +0,0 @@ - - - - - - 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/DaemonService/DaemonService.pro.user b/DaemonService/DaemonService.pro.user index bf619a6..d6aca7d 100644 --- a/DaemonService/DaemonService.pro.user +++ b/DaemonService/DaemonService.pro.user @@ -1,14 +1,14 @@ - + EnvironmentId - {6a2adf44-d351-4499-8d66-24024cfa2d9d} + {2d03fc4c-541a-4fa5-8f5c-ae92a1998dce} ProjectExplorer.Project.ActiveTarget - 0 + 1 ProjectExplorer.Project.EditorSettings @@ -64,14 +64,14 @@ ProjectExplorer.Project.Target.0 - Desktop Qt 5.6.2 MinGW 32bit - Desktop Qt 5.6.2 MinGW 32bit - qt.56.win32_mingw49_kit - 1 + Desktop Qt 5.11.2 MinGW 32bit + Desktop Qt 5.11.2 MinGW 32bit + qt.qt5.5112.win32_mingw53_kit + 0 0 0 - F:/Qt/build-DaemonService-Desktop_Qt_5_6_2_MinGW_32bit-Debug + E:/C++/Qt/build-DaemonService-Desktop_Qt_5_11_2_MinGW_32bit-Debug true @@ -89,11 +89,10 @@ Make Qt4ProjectManager.MakeStep - + false - false 2 Build @@ -106,11 +105,10 @@ Make Qt4ProjectManager.MakeStep - + true clean - false 1 Clean @@ -127,7 +125,7 @@ true - F:/Qt/build-DaemonService-Desktop_Qt_5_6_2_MinGW_32bit-Release + E:/C++/Qt/build-DaemonService-Desktop_Qt_5_11_2_MinGW_32bit-Release true @@ -138,18 +136,17 @@ false false - false + true true Make Qt4ProjectManager.MakeStep - + false - false 2 Build @@ -162,11 +159,10 @@ Make Qt4ProjectManager.MakeStep - + true clean - false 1 Clean @@ -183,7 +179,7 @@ true - F:/Qt/build-DaemonService-Desktop_Qt_5_6_2_MinGW_32bit-Profile + E:/C++/Qt/build-DaemonService-Desktop_Qt_5_11_2_MinGW_32bit-Profile true @@ -194,18 +190,17 @@ false true - false + true true Make Qt4ProjectManager.MakeStep - + false - false 2 Build @@ -218,11 +213,10 @@ Make Qt4ProjectManager.MakeStep - + true clean - false 1 Clean @@ -297,32 +291,278 @@ DaemonService - Qt4ProjectManager.Qt4RunConfiguration:F:/Qt/DaemonService/DaemonService.pro + 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.Target.1 + + Desktop Qt 5.6.2 MinGW 32bit2 + Desktop Qt 5.6.2 MinGW 32bit2 + qt.56.win32_mingw49_kit + 1 + 0 + 0 + + E:/C++/Qt/build-DaemonService-Desktop_Qt_5_6_2_MinGW_32bit2-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_6_2_MinGW_32bit2-Release + + + true + qmake + + QtProjectManager.QMakeBuildStep + false + + 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 + + Release + Release + Qt4ProjectManager.Qt4BuildConfiguration + 0 + true + + + E:/C++/Qt/build-DaemonService-Desktop_Qt_5_6_2_MinGW_32bit2-Profile + + + true + qmake + + QtProjectManager.QMakeBuildStep + true + + false + true + false + + + 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_6_2_MinGW_32bit2-Release 3768 false true - true false false true - - F:/Qt/build-DaemonService-Desktop_Qt_5_6_2_MinGW_32bit-Release 1 ProjectExplorer.Project.TargetCount - 1 + 2 ProjectExplorer.Project.Updater.FileVersion - 20 + 18 Version - 20 + 18 diff --git a/DaemonService.pro.user.6a2adf4.20 b/DaemonService/DaemonService.pro.user.6a2adf4.20 similarity index 98% rename from DaemonService.pro.user.6a2adf4.20 rename to DaemonService/DaemonService.pro.user.6a2adf4.20 index bf619a6..8ffe7ca 100644 --- a/DaemonService.pro.user.6a2adf4.20 +++ b/DaemonService/DaemonService.pro.user.6a2adf4.20 @@ -1,328 +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 - - + + + + + + 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/LICENSE b/DaemonService/LICENSE similarity index 100% rename from LICENSE rename to DaemonService/LICENSE diff --git a/DaemonService/dal.cpp b/DaemonService/dal.cpp index 0e31dcf..64bf092 100644 --- a/DaemonService/dal.cpp +++ b/DaemonService/dal.cpp @@ -88,6 +88,29 @@ QList DAL::getWhiteList(QString ip) return whitelist; } +void DAL::removeFromWhiteList(QString ip) +{ + QString sql = QString("DELETE 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()< portList); QList getWhiteList(QString ip); + void removeFromWhiteList(QString ip); + void removeFromWhiteList(QString ip, QList ports); bool isExistsBlackList(int port); bool isExistsBlackList(QString ip); bool addItemToBlackList(int port); + bool addItemToBlackList(QString ip); bool addItemToBlackList(QString ip, int port); + void removeFromBlackList(QString ip); QString getPortList(); void setPortList(QString portList); diff --git a/DaemonService/ipsechelper.cpp b/DaemonService/ipsechelper.cpp index 0261eb0..b98bd5a 100644 --- a/DaemonService/ipsechelper.cpp +++ b/DaemonService/ipsechelper.cpp @@ -16,12 +16,18 @@ void IpsecHelper::addItemToBlackList(QString ip, int port) { ExeCmd("add", "blacklist", ip, port); } - +void IpsecHelper::addItemToBlackList(QString ip) +{ + ExeCmd("add", "blacklist", ip); +} void IpsecHelper::removeItemFromBlackList(QString ip, int port) { ExeCmd("delete", "blacklist", ip, port); } - +void IpsecHelper::removeItemFromBlackList(QString ip) +{ + ExeCmd("delete", "blacklist", ip); +} void IpsecHelper::addItemToBlackList(int port) { ExeCmd("add", "blacklist", "any", port); diff --git a/DaemonService/ipsechelper.h b/DaemonService/ipsechelper.h index bb3722b..2e5a5f2 100644 --- a/DaemonService/ipsechelper.h +++ b/DaemonService/ipsechelper.h @@ -15,11 +15,13 @@ public: static void removeItemFromWhiteList(QString ip, int port); static void addItemToBlackList(QString ip, int port); + static void addItemToBlackList(QString ip); static void removeItemFromBlackList(QString ip, int port); + static void removeItemFromBlackList(QString ip); static void addItemToBlackList(int port); private: - static void ExeCmd(QString cmd, QString filterlist, QString srcaddr, int port); + static void ExeCmd(QString cmd, QString filterlist, QString srcaddr, int port = 0); }; #endif // IPSECHELPER_H diff --git a/DaemonService/main.cpp b/DaemonService/main.cpp index cce5077..b256d9a 100644 --- a/DaemonService/main.cpp +++ b/DaemonService/main.cpp @@ -37,19 +37,19 @@ void customMessageHandler(QtMsgType type, const QMessageLogContext &, const QStr switch (type) { case QtDebugMsg: //调试信息提示 - txtMessage = QString("%1 Debug(调试):\t%2").arg(QDateTime::currentDateTime().toString("yy/MM/dd HH:mm:ss.zzz")).arg(str); + 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.zzz")).arg(str); + 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.zzz")).arg(str); + 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.zzz")).arg(str); + txtMessage = QString("%1 Fatal(致命错误):\t%2").arg(QDateTime::currentDateTime().toString("yy/MM/dd HH:mm:ss")).arg(str); break; default: diff --git a/DaemonService/mainwindow.cpp b/DaemonService/mainwindow.cpp index d327808..275c5ba 100644 --- a/DaemonService/mainwindow.cpp +++ b/DaemonService/mainwindow.cpp @@ -156,3 +156,90 @@ void MainWindow::on_btnAddIP_clicked() 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()); + } +} + +void MainWindow::on_btnAddBlackIP_clicked() +{ + QString ip = ui->txtBlackIP->text(); + if (ip.isEmpty()) + { + log_append("请输入要加入黑名单的IP"); + return; + } + if (DAL::instance().isExistsBlackList(ip)) + { + log_append("该IP已存在黑名单"); + return; + } + + auto list = DAL::instance().getWhiteList(ip); + if (list.length() > 0) + { + log_append("正在将该ip从白名单中移出..."); + for (int i = 0; i < list.length(); ++i) + IpsecHelper::removeItemFromWhiteList(ip, list[i].Port); + DAL::instance().removeFromWhiteList(ip); + log_append("移出白名单完成"); + } + + IpsecHelper::addItemToBlackList(ip); + DAL::instance().addItemToBlackList(ip); + log_append("黑名单添加完成"); +} + +void MainWindow::on_btnRemoveBlackIP_clicked() +{ + QString ip = ui->txtBlackIP->text(); + if (ip.isEmpty()) + { + log_append("请输入要移出黑名单的IP"); + return; + } + if (!DAL::instance().isExistsBlackList(ip)) + { + log_append("该IP不存在于黑名单"); + return; + } + + IpsecHelper::addItemToBlackList(ip); + DAL::instance().removeFromBlackList(ip); + log_append("黑名单移出完成"); +} diff --git a/DaemonService/mainwindow.h b/DaemonService/mainwindow.h index fdfe206..3248035 100644 --- a/DaemonService/mainwindow.h +++ b/DaemonService/mainwindow.h @@ -27,6 +27,12 @@ private slots: void on_btnAddIP_clicked(); + void on_btnRemoveIP_clicked(); + + void on_btnAddBlackIP_clicked(); + + void on_btnRemoveBlackIP_clicked(); + private: Ui::MainWindow *ui; }; diff --git a/DaemonService/mainwindow.ui b/DaemonService/mainwindow.ui index 481c2e8..5e8a7b3 100644 --- a/DaemonService/mainwindow.ui +++ b/DaemonService/mainwindow.ui @@ -7,19 +7,19 @@ 0 0 700 - 320 + 400 700 - 320 + 400 700 - 320 + 400 @@ -32,7 +32,7 @@ 130 30 561 - 281 + 361 @@ -60,7 +60,7 @@ p, li { white-space: pre-wrap; } 10 - 270 + 350 111 41 @@ -125,7 +125,7 @@ p, li { white-space: pre-wrap; } 10 - 170 + 190 111 20 @@ -135,13 +135,88 @@ p, li { white-space: pre-wrap; } 10 - 190 - 111 + 210 + 51 23 - 将IP加入白名单 + + + + + + + + 70 + 210 + 51 + 23 + + + + - + + + + + + 10 + 170 + 54 + 12 + + + + 白名单IP: + + + + + + 10 + 250 + 54 + 12 + + + + 黑名单IP: + + + + + + 10 + 290 + 51 + 23 + + + + + + + + + + + 10 + 270 + 111 + 20 + + + + + + + 70 + 290 + 51 + 23 + + + + - diff --git a/DaemonService/worker.cpp b/DaemonService/worker.cpp index 07a8eae..e8ed537 100644 --- a/DaemonService/worker.cpp +++ b/DaemonService/worker.cpp @@ -37,33 +37,68 @@ void Worker::run() // + "sjavlkc907*$!@(.12i.dy1").toStr()) QString password = ip + "asdfas35.v;cxv-123ioer6719024yosjavlkc907*$!@(.12i.dy1iuew6f178934056xck3dy$^@1309uyrew"; - if (MD5Check(const_cast(data.toStdString().data()), const_cast(password.toStdString().data()), password.toStdString().length())) + 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); - for (int port : this->m_portList) + + + // 为了防止短时间内多次连接,检查最后一次连接的时间距离现在有多久 + // 如果不超过30秒,则将其从白名单中移除 + + for (int i = this->m_portList.length() - 1; i >= 0; --i) { - bool flag = false; - for (const auto &item : list) + int port = this->m_portList[i]; + int index; + for (index = 0; index < list.length(); ++index) { - if (item.Port == port) - { - flag = true; + if (list[index].Port == port) break; - } } - if (!flag) + 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()); + 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 (DAL::instance().updateWhiteList(ip, this->m_portList)) + if (this->m_portList.length() == 0 || DAL::instance().updateWhiteList(ip, this->m_portList)) qDebug("IP:%s 已连接", ip.toStdString().data()); else qWarning("Update failed!(更新失败)"); @@ -89,7 +124,7 @@ void Worker::run() DAL::instance().addItemToBlackList(ip, 8796); qDebug("IP:%s 已拉黑", ip.toStdString().data()); } - +end: // qDebug("Close Socket connection(关闭Socket连接)"); // 关闭socket连接 this->m_socket->close(); diff --git a/DaemonServiceInitializer.bat b/DaemonServiceInitializer.bat deleted file mode 100644 index 6c8a73e..0000000 --- a/DaemonServiceInitializer.bat +++ /dev/null @@ -1,21 +0,0 @@ -@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/README.md b/README.md index 3ebd5f9..f011be5 100644 --- a/README.md +++ b/README.md @@ -1,38 +1,37 @@ # DaemonService -ݿ -dal.cpp -dal.h +ʹ**Qt 5.6** ݿʹ**SQLite** - -ipsechelper.cpp -ipsechelper.h +ԭDz**windowsذȫ** -߳ -worker.cpp -worker.h +нͼ +![](images/DeamonService.png) -־ -log.cpp -log.h - -md5ࣨδʹã -md5.cpp -md5.h - -ӳء̷߳䡢 -daemonservice.cpp -daemonservice.h - -ػʼű -DaemonServiceInitializer.bat - -QtĿļ -DaemonService.pro - -Դļ -res.qrc -uac.rc - -ͼļ -Daemon.ico \ No newline at end of file +#### ļṹ +- ݿ + - dal.cpp + - dal.h +- + - ipsechelper.cpp + - ipsechelper.h +- ߳ + - worker.cpp + - worker.h +- ־ + - log.cpp + - log.h +- md5ࣨδʹã + - md5.cpp + - md5.h +- ӳء̷߳䡢 + - daemonservice.cpp + - daemonservice.h +- ػʼű + - DaemonServiceInitializer.bat +- QtĿļ + - DaemonService.pro +- Դļ + - res.qrc + - uac.rc +- ͼļ + - Daemon.ico \ No newline at end of file diff --git a/ReadMe.png b/ReadMe.png deleted file mode 100644 index 93935e918540eabae157226328c11ffa8a311f0e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 114784 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℘}CY#GMq@`TO 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 oK0ph zz6G>qIh#cXFvJue5j;#4H0d4jypUyr{Zl*FO^ESU8CR*bGWriO1L^>qZr6~#6`1o4 zQ@Y3T{9%uFf{l^7`!|8MY4sJBEa6eH8!p<%1xs7kjra)kgUd83;mmf{FfKk@A+6Ud za|MluAx0));Ub9SzH0gcKL5l(E zY#<&0AJ-J2Yr`3h(h3{Tq9ZKuf*=HZ&yVtJ?)QBXMS~vcy19QcEl$Vp)Ui_GC$Nu_ zEVDW6;2Y>FWSobJ(mbSR5~=5#o+@7zI{JP675dxQEZU=^L3vcuNPNZb7nl}NnpAl; zEo$F7f_71ct@9gH*lK!*R$P%~>7YcB&-N_7ErcVkykGmIg`Yr1_a=KjrfIrcX2J>D zy2U`ef~raGg^L*{VqHg)@HO6f*dyetMNPqyao*GUWj!5hdPLuwZzDZ>j!-O-B7ne$ zDBjX2t|#9_1lUKkx;_a;5sFK+ znjhBDu@{p=%pSWyni5wlq{H)ic2 znw6#3!@3mC+KCB0eH!p7;tNkQ*`{c0Wv8B2&#P7n-kKYL-j5emyjPA0{gQEUSiORW#Ms7VX?`tzWy7elJcwG;Sd#%v5f zVgjj~T`LJTFy28Smk&_Fqt6--VHnpd%Yvw5Z@pZIzaEO&h(h!NCz-F}En$)G}pHKx?su{*4Dj*i?W)&56h4d?-9F#tV*a{SUWp$2} zV(d%K#fV{O8H%?jQ&{xm^D!c?nhp-_VWeEBAPjme9FvC(pbs$b={!<<0{3iecpC`) zl%a?fCVDt)8|rwVX@2u)4~ws8Zw~TW%)^$ct_|PLx~WL+pI(fvEE=*E$W9JFa3U0|qH$`lV@ zF_BfPwo1zx`lC{L&(Duti83UNobM}`V{b$7McUu}RU0w93XIPmT!Fw8Wvf)qSTIa# z$T^Y=;9MQzxYgYy_{iQtf#hYB1ue;llzq*~zp?14-&x0vczs&&uT>il?ckbgMX=Ha zY!?VPp2%sLtqO-Icf9CEG|nW?|WkGPLYqpCR+B zdvmYyxmVp>;wBxFmJc9-#kdq%kZHV5us!+ys$_8otoBA7*ETGmaM4U=QB~>dI!uc4 zoH!o7Mvw!3ftwPfNkaNZTEtee-FtR{>UqIwx^Ia*%Rb$x-3*@teqt$d@z)-*kNYcT)bB{4D3=$@$kZs7!X4v6VU%{MCb z7MBfhOG!3jsQ(ekR?7dQs#U%%Ty9{~H(S{w^Ej&aCzJ>T%6MOM8e0a-Sn8*l_Aq!n zpjqq?KkaCG1MG9AJhY0xjdd06;$+MYjBRUBNx+;cL z9Pv+qOA@VBvJ^5WB5EM2eeT?)=D~GE*Wh8(%SJy@$A+V|HOwTkL{|o))pn65cgqjc zN*MGnFSY|ExS@0Xhe`$(p#7?@163SL4lR4s+{CEBnIV^mt=Xdf;>aGBoI7 zT8ov7Yj$F}Hg8j}sT~Sd{(-FI!#r$+Jz|`3Q znG?Z4D3ZM8R$MX?U~fgT^WT%>cErncK{n*{IdFFba%cY?D1VDU_6R|e{GAW~>LZY! zDM5U30Sud|V=CtVj)DQ3FGAkt?W)K0KY#t_7avHcKzD1BI3r?EkS`fY1&K;A!@&Os D;9+ub diff --git a/UAC.manifest b/UAC.manifest deleted file mode 100644 index b9b1f7f..0000000 --- a/UAC.manifest +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - - - - \ No newline at end of file diff --git a/daemonservice.cpp b/daemonservice.cpp deleted file mode 100644 index 13cd81e..0000000 --- a/daemonservice.cpp +++ /dev/null @@ -1,25 +0,0 @@ -#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 deleted file mode 100644 index 976661c..0000000 --- a/daemonservice.h +++ /dev/null @@ -1,45 +0,0 @@ -#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 deleted file mode 100644 index 64bf092..0000000 --- a/dal.cpp +++ /dev/null @@ -1,281 +0,0 @@ -#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); - void removeFromWhiteList(QString ip, QList ports); - - bool isExistsBlackList(int port); - bool isExistsBlackList(QString ip); - - bool addItemToBlackList(int port); - bool addItemToBlackList(QString ip); - bool addItemToBlackList(QString ip, int port); - void removeFromBlackList(QString ip); - - QString getPortList(); - void setPortList(QString portList); -private: - DAL(); -}; - -#endif // DAL_H diff --git a/images/DeamonService.png b/images/DeamonService.png new file mode 100644 index 0000000000000000000000000000000000000000..6154e9e52faf6ab29c577d82755f79c7e16009db GIT binary patch literal 9330 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 -#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::addItemToBlackList(QString ip) -{ - ExeCmd("add", "blacklist", ip); -} -void IpsecHelper::removeItemFromBlackList(QString ip, int port) -{ - ExeCmd("delete", "blacklist", ip, port); -} -void IpsecHelper::removeItemFromBlackList(QString ip) -{ - ExeCmd("delete", "blacklist", ip); -} -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 deleted file mode 100644 index 2e5a5f2..0000000 --- a/ipsechelper.h +++ /dev/null @@ -1,27 +0,0 @@ -#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 addItemToBlackList(QString ip); - static void removeItemFromBlackList(QString ip, int port); - static void removeItemFromBlackList(QString ip); - - static void addItemToBlackList(int port); -private: - static void ExeCmd(QString cmd, QString filterlist, QString srcaddr, int port = 0); -}; - -#endif // IPSECHELPER_H diff --git a/log.cpp b/log.cpp deleted file mode 100644 index 1d04e98..0000000 --- a/log.cpp +++ /dev/null @@ -1,14 +0,0 @@ -#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 deleted file mode 100644 index 91a1848..0000000 --- a/log.h +++ /dev/null @@ -1,26 +0,0 @@ -#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 deleted file mode 100644 index b256d9a..0000000 --- a/main.cpp +++ /dev/null @@ -1,63 +0,0 @@ -#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 deleted file mode 100644 index 275c5ba..0000000 --- a/mainwindow.cpp +++ /dev/null @@ -1,245 +0,0 @@ -#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()); - } -} - -void MainWindow::on_btnAddBlackIP_clicked() -{ - QString ip = ui->txtBlackIP->text(); - if (ip.isEmpty()) - { - log_append("请输入要加入黑名单的IP"); - return; - } - if (DAL::instance().isExistsBlackList(ip)) - { - log_append("该IP已存在黑名单"); - return; - } - - auto list = DAL::instance().getWhiteList(ip); - if (list.length() > 0) - { - log_append("正在将该ip从白名单中移出..."); - for (int i = 0; i < list.length(); ++i) - IpsecHelper::removeItemFromWhiteList(ip, list[i].Port); - DAL::instance().removeFromWhiteList(ip); - log_append("移出白名单完成"); - } - - IpsecHelper::addItemToBlackList(ip); - DAL::instance().addItemToBlackList(ip); - log_append("黑名单添加完成"); -} - -void MainWindow::on_btnRemoveBlackIP_clicked() -{ - QString ip = ui->txtBlackIP->text(); - if (ip.isEmpty()) - { - log_append("请输入要移出黑名单的IP"); - return; - } - if (!DAL::instance().isExistsBlackList(ip)) - { - log_append("该IP不存在于黑名单"); - return; - } - - IpsecHelper::addItemToBlackList(ip); - DAL::instance().removeFromBlackList(ip); - log_append("黑名单移出完成"); -} diff --git a/mainwindow.h b/mainwindow.h deleted file mode 100644 index 3248035..0000000 --- a/mainwindow.h +++ /dev/null @@ -1,40 +0,0 @@ -#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(); - - void on_btnAddBlackIP_clicked(); - - void on_btnRemoveBlackIP_clicked(); - -private: - Ui::MainWindow *ui; -}; - -#endif // MAINWINDOW_H diff --git a/mainwindow.ui b/mainwindow.ui deleted file mode 100644 index 5e8a7b3..0000000 --- a/mainwindow.ui +++ /dev/null @@ -1,227 +0,0 @@ - - - MainWindow - - - - 0 - 0 - 700 - 400 - - - - - 700 - 400 - - - - - 700 - 400 - - - - DaemonService - - - - - - 130 - 30 - 561 - 361 - - - - <!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 - 350 - 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: - - - - - - 10 - 250 - 54 - 12 - - - - 黑名单IP: - - - - - - 10 - 290 - 51 - 23 - - - - + - - - - - - 10 - 270 - 111 - 20 - - - - - - - 70 - 290 - 51 - 23 - - - - - - - - - - - - - diff --git a/md5.cpp b/md5.cpp deleted file mode 100644 index ab7370d..0000000 --- a/md5.cpp +++ /dev/null @@ -1,394 +0,0 @@ -#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 deleted file mode 100644 index 67ec8b5..0000000 --- a/md5.h +++ /dev/null @@ -1,10 +0,0 @@ -#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 deleted file mode 100644 index 5aeac4e..0000000 --- a/model.h +++ /dev/null @@ -1,26 +0,0 @@ -#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 deleted file mode 100644 index 4e72c4f..0000000 --- a/res.qrc +++ /dev/null @@ -1,5 +0,0 @@ - - - Daemon.ico - - diff --git a/uac.rc b/uac.rc deleted file mode 100644 index 686301f..0000000 --- a/uac.rc +++ /dev/null @@ -1 +0,0 @@ -1 24 DISCARDABLE "UAC.manifest" \ No newline at end of file diff --git a/worker.cpp b/worker.cpp deleted file mode 100644 index e8ed537..0000000 --- a/worker.cpp +++ /dev/null @@ -1,132 +0,0 @@ -#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() - 1; 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()); - 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 deleted file mode 100644 index b91f3f9..0000000 --- a/worker.h +++ /dev/null @@ -1,32 +0,0 @@ -#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