From c25891c8f503b9ba1b053e8f354d549896f8190d Mon Sep 17 00:00:00 2001 From: maro5397 Date: Thu, 16 Dec 2021 13:37:02 -0500 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8=20feat:=20dotdot=20prevent=20and=20he?= =?UTF-8?q?ader=20modify?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/uiserver-test/main.cpp | 17 ++++ app/uiserver-test/uiserver-test.pro | 25 ++++++ app/uiserver-test/uiserver.cpp | 121 ++++++++++++++++++++++++++++ app/uiserver-test/uiserver.h | 30 +++++++ 4 files changed, 193 insertions(+) create mode 100644 app/uiserver-test/main.cpp create mode 100644 app/uiserver-test/uiserver-test.pro create mode 100644 app/uiserver-test/uiserver.cpp create mode 100644 app/uiserver-test/uiserver.h diff --git a/app/uiserver-test/main.cpp b/app/uiserver-test/main.cpp new file mode 100644 index 0000000..7906130 --- /dev/null +++ b/app/uiserver-test/main.cpp @@ -0,0 +1,17 @@ +#include +#include "uiserver.h" + +int main(int argc, char *argv[]) +{ + QCoreApplication a(argc, argv); + + UIServer uiserver; + uiserver.rootdir_ = "../../bin/webui"; + uiserver.start(80); + + a.exec(); + + uiserver.stop(); + + return 0; +} diff --git a/app/uiserver-test/uiserver-test.pro b/app/uiserver-test/uiserver-test.pro new file mode 100644 index 0000000..28cc409 --- /dev/null +++ b/app/uiserver-test/uiserver-test.pro @@ -0,0 +1,25 @@ +QT -= gui + +CONFIG += c++20 +TEMPLATE = app +CONFIG += qt + +include(../../cp.pri) + +LIBS += -L../../../opensocket/lib -lopensocket -lssl -lcrypto -lpthread -lglog + +SOURCES += \ + main.cpp \ + uiserver.cpp \ + ../../src/httprequest.cpp \ + ../../src/httpresponse.cpp \ + ../../../opensocket/src/*.cpp \ + ../../../opensocket/src/base/*.cpp + +HEADERS += \ + uiserver.h \ + ../../src/httprequest.h \ + ../../src/httpresponse.h \ + ../../src/http.h \ + ../../../opensocket/src/*.h \ + ../../../opensocket/src/base/*.h diff --git a/app/uiserver-test/uiserver.cpp b/app/uiserver-test/uiserver.cpp new file mode 100644 index 0000000..eeff46b --- /dev/null +++ b/app/uiserver-test/uiserver.cpp @@ -0,0 +1,121 @@ +#include "uiserver.h" +#include + +UIServer::UIServer() { +} + +void UIServer::handleClnt(TcpClientSocket *clntsock) { + + char buffer[BUFSIZE]; + int len; + + while((len = clntsock->recv(buffer, BUFSIZE)) != -1) { + uirequest_.resetData(); + if(len == 0) { + DLOG(INFO) << "clntsock is shutdown"; + return; + } + uirequest_.addRequestPacket(buffer, len); + uirequest_.parseRequestPacket(); + setHttpResponse(); + clntsock->send((char*)uiresponse_.getResponseData()->c_str(), uiresponse_.getResponseSize()); + } + return; +} + +void UIServer::setHttpResponse() { + std::string path = uirequest_.getURL(); + uiresponse_.resetData(); + int size = 0; + DLOG(INFO) << "request path:" << path; + +// if(path.ends_with(".css")) { +// uiresponse_.setHTTPHeader("Content-Type", "text/css;charset=UTF-8"); +// } +// else if(path.ends_with(".js")) { +// uiresponse_.setHTTPHeader("Content-Type", "text/javascript;charset=UTF-8"); +// } +// else { +// uiresponse_.setHTTPHeader("Content-Type", "text/html"); +// } + + if(denyDotDotPacket(path)) { + return; + } + + if(path == "/") { + size = getWebUIData("/index.html"); + uiresponse_.setResponseBody(ui_); + } + else if(path == "/Start") { + size = 5; + uiresponse_.setResponseBody("start"); + } + else if(path == "/Stop") { + size = 4; + uiresponse_.setResponseBody("stop"); + } + else { + size = getWebUIData(path); + uiresponse_.setResponseBody(ui_); + } + + std::string len = std::to_string(size); + + uiresponse_.setProtocol(HTTP1_1); + uiresponse_.setStatusCode(200); + uiresponse_.setReasonPhrase(); + uiresponse_.setHTTPHeader("Connection", "keep-alive"); + uiresponse_.setHTTPHeader("Content-Length", len.c_str()); + uiresponse_.setHTTPHeader("Date", getDateTime()); + uiresponse_.setHTTPHeader("Keep-Alive", "timeout=5, max=100"); + uiresponse_.setHTTPHeader("Server", "UIServer"); + uiresponse_.makeResponse(); +} + +int UIServer::getWebUIData(std::string path) { + DLOG(INFO) << "Get local data from" << rootdir_+path; + std::ifstream fin(rootdir_+path); + int size = 0; + + if(fin.is_open()){ + fin.seekg(0, std::ios::end); + size = fin.tellg(); + fin.seekg(0, std::ios::beg); + fin.read(ui_, size); + } + return size; +} + +std::string UIServer::getDateTime() { + char date[30] = {'\0'}; + + time_t now = time(0); + tm *gmtm = gmtime(&now); + char* dt = asctime(gmtm); + + char mon[4]; + char dayofweek[4]; + int year, day, hour, min, sec; + + sscanf(dt, "%s %s %d %d:%d:%d %d\n", dayofweek, mon, &day, &hour, &min, &sec, &year); + sprintf(date, "%s, %02d %s %d %02d:%02d:%02d GMT", dayofweek, day, mon, year, hour, min, sec); + std::string dateheader = date; + return dateheader; +} + +bool UIServer::denyDotDotPacket(std::string path) +{ + if(path.find("..") != std::string::npos) { + DLOG(INFO) << "there is .. string from path:" << path; + uiresponse_.setProtocol(HTTP1_1); + uiresponse_.setStatusCode(403); + uiresponse_.setReasonPhrase(); + uiresponse_.setHTTPHeader("Date", getDateTime()); + uiresponse_.setHTTPHeader("Server", "UIServer"); + uiresponse_.makeResponse(); + return true; + } + return false; +} + diff --git a/app/uiserver-test/uiserver.h b/app/uiserver-test/uiserver.h new file mode 100644 index 0000000..6233867 --- /dev/null +++ b/app/uiserver-test/uiserver.h @@ -0,0 +1,30 @@ +#pragma once +#include "tcpserver.h" +#include "httprequest.h" +#include "httpresponse.h" + +#include +#include +#include +#include + +class UIServer : public TcpServer +{ + HTTPRequest uirequest_; + HTTPResponse uiresponse_; + char ui_[BUFSIZE]; + +public: + std::string rootdir_; + +public: + UIServer(); + ~UIServer() {} + +protected: + void handleClnt(TcpClientSocket* clntsock) override; + void setHttpResponse(); + int getWebUIData(std::string path); + std::string getDateTime(); + bool denyDotDotPacket(std::string path); +};