Adapt Drogon to take advitange of Trantor TLS refactor (#1505)
Co-authored-by: marty1885 <marty1885@gmail.com>
This commit is contained in:
parent
120aaf249d
commit
122a42cd4f
|
@ -1,4 +1,3 @@
|
|||
[submodule "trantor"]
|
||||
path = trantor
|
||||
url = https://github.com/an-tao/trantor.git
|
||||
|
||||
|
|
|
@ -505,20 +505,6 @@ endif (BUILD_TESTING)
|
|||
find_package(ZLIB REQUIRED)
|
||||
target_link_libraries(${PROJECT_NAME} PRIVATE ZLIB::ZLIB)
|
||||
|
||||
find_package(OpenSSL)
|
||||
if (OpenSSL_FOUND)
|
||||
target_link_libraries(${PROJECT_NAME} PRIVATE OpenSSL::SSL OpenSSL::Crypto)
|
||||
else (OpenSSL_FOUND)
|
||||
set(DROGON_SOURCES
|
||||
${DROGON_SOURCES}
|
||||
lib/src/ssl_funcs/Md5.cc
|
||||
lib/src/ssl_funcs/Sha1.cc)
|
||||
set(private_headers
|
||||
${private_headers}
|
||||
lib/src/ssl_funcs/Md5.h
|
||||
lib/src/ssl_funcs/Sha1.h)
|
||||
endif (OpenSSL_FOUND)
|
||||
|
||||
execute_process(COMMAND "git" rev-parse HEAD
|
||||
WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}"
|
||||
OUTPUT_VARIABLE GIT_SHA1
|
||||
|
|
|
@ -5,8 +5,8 @@
|
|||
//ssl:The global SSL settings. "key" and "cert" are the path to the SSL key and certificate. While
|
||||
// "conf" is an array of 1 or 2-element tuples that supplies file style options for `SSL_CONF_cmd`.
|
||||
"ssl": {
|
||||
"cert": "../../trantor/trantor/tests/server.pem",
|
||||
"key": "../../trantor/trantor/tests/server.pem",
|
||||
"cert": "../../trantor/trantor/tests/server.crt",
|
||||
"key": "../../trantor/trantor/tests/server.key",
|
||||
"conf": [
|
||||
//["Options", "-SessionTicket"],
|
||||
//["Options", "Compression"]
|
||||
|
|
|
@ -5,8 +5,8 @@
|
|||
//ssl:The global SSL settings. "key" and "cert" are the path to the SSL key and certificate. While
|
||||
// "conf" is an array of 1 or 2-element tuples that supplies file style options for `SSL_CONF_cmd`.
|
||||
"ssl": {
|
||||
"cert": "../../trantor/trantor/tests/server.pem",
|
||||
"key": "../../trantor/trantor/tests/server.pem",
|
||||
"cert": "../../trantor/trantor/tests/server.crt",
|
||||
"key": "../../trantor/trantor/tests/server.key",
|
||||
"conf": [
|
||||
//["Options", "-SessionTicket"],
|
||||
//["Options", "Compression"]
|
||||
|
|
|
@ -15,7 +15,9 @@
|
|||
#include "version.h"
|
||||
#include <drogon/config.h>
|
||||
#include <drogon/version.h>
|
||||
#include <drogon/utils/Utilities.h>
|
||||
#include <trantor/net/Resolver.h>
|
||||
#include <trantor/utils/Utilities.h>
|
||||
#include <iostream>
|
||||
|
||||
using namespace drogon_ctl;
|
||||
|
@ -30,6 +32,8 @@ static const char banner[] =
|
|||
|
||||
void version::handleCommand(std::vector<std::string> ¶meters)
|
||||
{
|
||||
const auto tlsBackend = trantor::utils::tlsBackend();
|
||||
const bool tlsSupported = drogon::utils::supportsTls();
|
||||
std::cout << banner << std::endl;
|
||||
std::cout << "A utility for drogon" << std::endl;
|
||||
std::cout << "Version: " << DROGON_VERSION << std::endl;
|
||||
|
@ -43,11 +47,7 @@ void version::handleCommand(std::vector<std::string> ¶meters)
|
|||
<< (LIBPQ_SUPPORTS_BATCH_MODE ? "yes)\n" : "no)\n")
|
||||
<< " mariadb: " << (USE_MYSQL ? "yes\n" : "no\n")
|
||||
<< " sqlite3: " << (USE_SQLITE3 ? "yes\n" : "no\n");
|
||||
#ifdef OpenSSL_FOUND
|
||||
std::cout << " openssl: yes\n";
|
||||
#else
|
||||
std::cout << " openssl: no\n";
|
||||
#endif
|
||||
std::cout << " ssl/tls backend: " << tlsBackend << "\n";
|
||||
#ifdef USE_BROTLI
|
||||
std::cout << " brotli: yes\n";
|
||||
#else
|
||||
|
|
|
@ -4,8 +4,8 @@
|
|||
/*
|
||||
//ssl: The global ssl files setting
|
||||
"ssl": {
|
||||
"cert": "../../trantor/trantor/tests/server.pem",
|
||||
"key": "../../trantor/trantor/tests/server.pem"
|
||||
"cert": "../../trantor/trantor/tests/server.crt",
|
||||
"key": "../../trantor/trantor/tests/server.key"
|
||||
},*/
|
||||
"listeners": [{
|
||||
//address: Ip address,0.0.0.0 by default
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
#include <drogon/UploadFile.h>
|
||||
#include <json/json.h>
|
||||
#include <trantor/net/InetAddress.h>
|
||||
#include <trantor/net/Certificate.h>
|
||||
#include <trantor/utils/Date.h>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
@ -341,6 +342,13 @@ class DROGON_EXPORT HttpRequest
|
|||
return creationDate();
|
||||
}
|
||||
|
||||
// Return the peer certificate (if any)
|
||||
virtual const trantor::CertificatePtr &peerCertificate() const = 0;
|
||||
const trantor::CertificatePtr &getPeerCertificate() const
|
||||
{
|
||||
return peerCertificate();
|
||||
}
|
||||
|
||||
/// Get the Json object of the request
|
||||
/**
|
||||
* The content type of the request must be 'application/json',
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
|
||||
#include <drogon/exports.h>
|
||||
#include <drogon/utils/string_view.h>
|
||||
#include <trantor/net/Certificate.h>
|
||||
#include <drogon/DrClassMap.h>
|
||||
#include <drogon/Cookie.h>
|
||||
#include <drogon/HttpTypes.h>
|
||||
|
@ -336,6 +337,16 @@ class DROGON_EXPORT HttpResponse
|
|||
*/
|
||||
virtual void setPassThrough(bool flag) = 0;
|
||||
|
||||
/**
|
||||
* @brief Get the certificate of the peer, if any.
|
||||
* @return The certificate of the peer. nullptr is none.
|
||||
*/
|
||||
virtual const trantor::CertificatePtr &peerCertificate() const = 0;
|
||||
const trantor::CertificatePtr &getPeerCertificate() const
|
||||
{
|
||||
return peerCertificate();
|
||||
}
|
||||
|
||||
/* The following methods are a series of factory methods that help users
|
||||
* create response objects. */
|
||||
|
||||
|
|
|
@ -160,6 +160,7 @@ enum class ReqResult
|
|||
Timeout,
|
||||
HandshakeError,
|
||||
InvalidCertificate,
|
||||
EncryptionFailure,
|
||||
};
|
||||
|
||||
enum class WebSocketMessageType
|
||||
|
@ -190,6 +191,8 @@ inline string_view to_string_view(drogon::ReqResult result)
|
|||
return "Handshake error";
|
||||
case ReqResult::InvalidCertificate:
|
||||
return "Invalid certificate";
|
||||
case ReqResult::EncryptionFailure:
|
||||
return "Unrecoverable encryption failure";
|
||||
default:
|
||||
return "Unknown error";
|
||||
}
|
||||
|
|
|
@ -134,6 +134,30 @@ inline std::string getMd5(const std::string &originalString)
|
|||
return getMd5(originalString.data(), originalString.length());
|
||||
}
|
||||
|
||||
DROGON_EXPORT std::string getSha1(const char *data, const size_t dataLen);
|
||||
inline std::string getSha1(const std::string &originalString)
|
||||
{
|
||||
return getSha1(originalString.data(), originalString.length());
|
||||
}
|
||||
|
||||
DROGON_EXPORT std::string getSha256(const char *data, const size_t dataLen);
|
||||
inline std::string getSha256(const std::string &originalString)
|
||||
{
|
||||
return getSha256(originalString.data(), originalString.length());
|
||||
}
|
||||
|
||||
DROGON_EXPORT std::string getSha3(const char *data, const size_t dataLen);
|
||||
inline std::string getSha3(const std::string &originalString)
|
||||
{
|
||||
return getSha3(originalString.data(), originalString.length());
|
||||
}
|
||||
|
||||
DROGON_EXPORT std::string getBlake2b(const char *data, const size_t dataLen);
|
||||
inline std::string getBlake2b(const std::string &originalString)
|
||||
{
|
||||
return getBlake2b(originalString.data(), originalString.length());
|
||||
}
|
||||
|
||||
/// Commpress or decompress data using gzip lib.
|
||||
/**
|
||||
* @param data the input data
|
||||
|
@ -300,12 +324,18 @@ DROGON_EXPORT void replaceAll(std::string &s,
|
|||
* @param size number of bytes to generate
|
||||
*
|
||||
* @return true if generation is successfull. False otherwise
|
||||
*
|
||||
* @note DO NOT abuse this function. Especially if Drogon is built without
|
||||
* OpenSSL. Entropy running low is a real issue.
|
||||
*/
|
||||
DROGON_EXPORT bool secureRandomBytes(void *ptr, size_t size);
|
||||
|
||||
/**
|
||||
* @brief Generates cryptographically secure random string.
|
||||
*
|
||||
* @param size number of characters to generate
|
||||
*
|
||||
* @return the random string
|
||||
*/
|
||||
DROGON_EXPORT std::string secureRandomString(size_t size);
|
||||
|
||||
template <typename T>
|
||||
typename std::enable_if<internal::CanConvertFromStringStream<T>::value, T>::type
|
||||
fromString(const std::string &p) noexcept(false)
|
||||
|
@ -409,6 +439,8 @@ inline bool fromString<bool>(const std::string &p) noexcept(false)
|
|||
throw std::runtime_error("Can't convert from string '" + p + "' to bool");
|
||||
}
|
||||
|
||||
DROGON_EXPORT bool supportsTls() noexcept;
|
||||
|
||||
namespace internal
|
||||
{
|
||||
DROGON_EXPORT extern const size_t fixedRandomNumber;
|
||||
|
|
|
@ -545,10 +545,7 @@ class HttpAppFrameworkImpl final : public HttpAppFramework
|
|||
|
||||
bool supportSSL() const override
|
||||
{
|
||||
#ifdef OpenSSL_FOUND
|
||||
return true;
|
||||
#endif
|
||||
return false;
|
||||
return trantor::utils::tlsBackend() != "None";
|
||||
}
|
||||
|
||||
size_t getCurrentThreadIndex() const override
|
||||
|
|
|
@ -37,19 +37,20 @@ void HttpClientImpl::createTcpClient()
|
|||
tcpClientPtr_ =
|
||||
std::make_shared<trantor::TcpClient>(loop_, serverAddr_, "httpClient");
|
||||
|
||||
#ifdef OpenSSL_FOUND
|
||||
if (useSSL_)
|
||||
if (useSSL_ && utils::supportsTls())
|
||||
{
|
||||
LOG_TRACE << "useOldTLS=" << useOldTLS_;
|
||||
LOG_TRACE << "domain=" << domain_;
|
||||
tcpClientPtr_->enableSSL(useOldTLS_,
|
||||
validateCert_,
|
||||
domain_,
|
||||
sslConfCmds_,
|
||||
clientCertPath_,
|
||||
clientKeyPath_);
|
||||
auto policy = trantor::TLSPolicy::defaultClientPolicy();
|
||||
policy->setUseOldTLS(useOldTLS_)
|
||||
.setValidate(validateCert_)
|
||||
.setHostname(domain_)
|
||||
.setConfCmds(sslConfCmds_)
|
||||
.setCertPath(clientCertPath_)
|
||||
.setKeyPath(clientKeyPath_);
|
||||
tcpClientPtr_->enableSSL(std::move(policy));
|
||||
}
|
||||
#endif
|
||||
|
||||
auto thisPtr = shared_from_this();
|
||||
std::weak_ptr<HttpClientImpl> weakPtr = thisPtr;
|
||||
|
||||
|
@ -126,6 +127,8 @@ void HttpClientImpl::createTcpClient()
|
|||
thisPtr->onError(ReqResult::HandshakeError);
|
||||
else if (err == trantor::SSLError::kSSLInvalidCertificate)
|
||||
thisPtr->onError(ReqResult::InvalidCertificate);
|
||||
else if (err == trantor::SSLError::kSSLProtocolError)
|
||||
thisPtr->onError(ReqResult::EncryptionFailure);
|
||||
else
|
||||
{
|
||||
LOG_FATAL << "Invalid value for SSLError";
|
||||
|
@ -159,12 +162,12 @@ HttpClientImpl::HttpClientImpl(trantor::EventLoop *loop,
|
|||
lowerHost.end(),
|
||||
lowerHost.begin(),
|
||||
[](unsigned char c) { return tolower(c); });
|
||||
if (lowerHost.find("https://") != std::string::npos)
|
||||
if (lowerHost.find("https://") == 0)
|
||||
{
|
||||
useSSL_ = true;
|
||||
lowerHost = lowerHost.substr(8);
|
||||
}
|
||||
else if (lowerHost.find("http://") != std::string::npos)
|
||||
else if (lowerHost.find("http://") == 0)
|
||||
{
|
||||
useSSL_ = false;
|
||||
lowerHost = lowerHost.substr(7);
|
||||
|
@ -621,6 +624,7 @@ void HttpClientImpl::onRecvMessage(const trantor::TcpConnectionPtr &connPtr,
|
|||
if (responseParser->gotAll())
|
||||
{
|
||||
auto resp = responseParser->responseImpl();
|
||||
resp->setPeerCertificate(connPtr->peerCertificate());
|
||||
responseParser->reset();
|
||||
bytesReceived_ += (msgSize - msg->readableBytes());
|
||||
msgSize = msg->readableBytes();
|
||||
|
|
|
@ -128,6 +128,16 @@ std::string HttpFileImpl::getMd5() const noexcept
|
|||
return utils::getMd5(fileContent_.data(), fileContent_.size());
|
||||
}
|
||||
|
||||
std::string HttpFileImpl::getSha256() const noexcept
|
||||
{
|
||||
return utils::getSha256(fileContent_.data(), fileContent_.size());
|
||||
}
|
||||
|
||||
std::string HttpFileImpl::getSha3() const noexcept
|
||||
{
|
||||
return utils::getSha3(fileContent_.data(), fileContent_.size());
|
||||
}
|
||||
|
||||
const std::string &HttpFile::getFileName() const noexcept
|
||||
{
|
||||
return implPtr_->getFileName();
|
||||
|
|
|
@ -116,8 +116,12 @@ class HttpFileImpl
|
|||
return parseFileType(getFileExtension());
|
||||
}
|
||||
|
||||
/// Return the md5 string of the file
|
||||
/// Return md5 hash of the file
|
||||
std::string getMd5() const noexcept;
|
||||
// Return sha1 hash of the file
|
||||
std::string getSha256() const noexcept;
|
||||
// Return sha512 hash of the file
|
||||
std::string getSha3() const noexcept;
|
||||
// int saveTo(const std::string &pathAndFileName) const;
|
||||
int saveTo(const filesystem::path &pathAndFileName) const noexcept;
|
||||
void setRequest(const HttpRequestPtr &req) noexcept
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
#include <drogon/utils/Utilities.h>
|
||||
#include <trantor/net/EventLoop.h>
|
||||
#include <trantor/net/InetAddress.h>
|
||||
#include <trantor/net/Certificate.h>
|
||||
#include <trantor/utils/Logger.h>
|
||||
#include <trantor/utils/MsgBuffer.h>
|
||||
#include <trantor/utils/NonCopyable.h>
|
||||
|
@ -74,6 +75,7 @@ class HttpRequestImpl : public HttpRequest
|
|||
contentTypeString_.clear();
|
||||
keepAlive_ = true;
|
||||
jsonParsingErrorPtr_.reset();
|
||||
peerCertificate_.reset();
|
||||
}
|
||||
trantor::EventLoop *getLoop()
|
||||
{
|
||||
|
@ -231,6 +233,11 @@ class HttpRequestImpl : public HttpRequest
|
|||
return creationDate_;
|
||||
}
|
||||
|
||||
const trantor::CertificatePtr &peerCertificate() const override
|
||||
{
|
||||
return peerCertificate_;
|
||||
}
|
||||
|
||||
void setCreationDate(const trantor::Date &date)
|
||||
{
|
||||
creationDate_ = date;
|
||||
|
@ -246,6 +253,11 @@ class HttpRequestImpl : public HttpRequest
|
|||
local_ = local;
|
||||
}
|
||||
|
||||
void setPeerCertificate(const trantor::CertificatePtr &cert)
|
||||
{
|
||||
peerCertificate_ = cert;
|
||||
}
|
||||
|
||||
void addHeader(const char *start, const char *colon, const char *end);
|
||||
|
||||
void removeHeader(std::string key) override
|
||||
|
@ -561,6 +573,7 @@ class HttpRequestImpl : public HttpRequest
|
|||
trantor::InetAddress peer_;
|
||||
trantor::InetAddress local_;
|
||||
trantor::Date creationDate_;
|
||||
trantor::CertificatePtr peerCertificate_;
|
||||
std::unique_ptr<CacheFile> cacheFilePtr_;
|
||||
mutable std::unique_ptr<std::string> jsonParsingErrorPtr_;
|
||||
std::unique_ptr<std::string> expectPtr_;
|
||||
|
|
|
@ -316,6 +316,14 @@ class DROGON_EXPORT HttpResponseImpl : public HttpResponse
|
|||
{
|
||||
return sendfileRange_;
|
||||
}
|
||||
const trantor::CertificatePtr &peerCertificate() const override
|
||||
{
|
||||
return peerCertificate_;
|
||||
}
|
||||
void setPeerCertificate(const trantor::CertificatePtr &cert)
|
||||
{
|
||||
peerCertificate_ = cert;
|
||||
}
|
||||
void setSendfile(const std::string &filename)
|
||||
{
|
||||
sendfileName_ = filename;
|
||||
|
@ -472,6 +480,7 @@ class DROGON_EXPORT HttpResponseImpl : public HttpResponse
|
|||
mutable std::shared_ptr<Json::Value> jsonPtr_;
|
||||
|
||||
std::shared_ptr<trantor::MsgBuffer> fullHeaderString_;
|
||||
trantor::CertificatePtr peerCertificate_;
|
||||
mutable std::shared_ptr<trantor::MsgBuffer> httpString_;
|
||||
mutable size_t datePos_{static_cast<size_t>(-1)};
|
||||
mutable int64_t httpStringDate_{-1};
|
||||
|
|
|
@ -179,6 +179,7 @@ void HttpServer::onMessage(const TcpConnectionPtr &conn, MsgBuffer *buf)
|
|||
req->setLocalAddr(conn->localAddr());
|
||||
req->setCreationDate(trantor::Date::date());
|
||||
req->setSecure(conn->isSSLConnection());
|
||||
req->setPeerCertificate(conn->peerCertificate());
|
||||
if (requestParser->firstReq() && isWebSocket(req))
|
||||
{
|
||||
auto wsConn = std::make_shared<WebSocketConnectionImpl>(conn);
|
||||
|
@ -505,29 +506,29 @@ static std::size_t chunkingCallback(
|
|||
// Alternative code if there are client softwares that do not support chunk
|
||||
// size with leading zeroes
|
||||
// auto nHeaderLen =
|
||||
//#ifdef _WIN32
|
||||
// #ifdef _WIN32
|
||||
// sprintf_s(pBuffer,
|
||||
// nHeaderSize, "%llx\r",
|
||||
// nDataSize);
|
||||
//#else
|
||||
// #else
|
||||
// sprintf(pBuffer, "%lx\r",
|
||||
// nDataSize);
|
||||
//#endif
|
||||
// #endif
|
||||
// pBuffer[nHeaderLen++] = '\n';
|
||||
// if (nHeaderLen < nHeaderSize) // smaller that what was reserved ->
|
||||
// move data
|
||||
//#ifdef _WIN32
|
||||
// #ifdef _WIN32
|
||||
// memmove_s(pBuffer +
|
||||
// nHeaderLen,
|
||||
// nSize - nHeaderLen,
|
||||
// pBuffer +
|
||||
// nHeaderSize,
|
||||
// nDataSize + 2);
|
||||
//#else
|
||||
// #else
|
||||
// memmove(pBuffer + nHeaderLen,
|
||||
// pBuffer + nHeaderSize,
|
||||
// nDataSize + 2);
|
||||
//#endif
|
||||
// #endif
|
||||
// return nHeaderLen + nDataSize + 2;
|
||||
}
|
||||
|
||||
|
|
|
@ -85,13 +85,21 @@ class HttpServer : trantor::NonCopyable
|
|||
void start();
|
||||
void stop();
|
||||
|
||||
void enableSSL(
|
||||
[[deprecated("Use enableSSL(SSLPolicy) instead")]] void enableSSL(
|
||||
const std::string &certPath,
|
||||
const std::string &keyPath,
|
||||
bool useOldTLS,
|
||||
const std::vector<std::pair<std::string, std::string>> &sslConfCmds)
|
||||
{
|
||||
server_.enableSSL(certPath, keyPath, useOldTLS, sslConfCmds);
|
||||
auto policy =
|
||||
trantor::TLSPolicy::defaultServerPolicy(certPath, keyPath);
|
||||
policy->setConfCmds(sslConfCmds).setUseOldTLS(useOldTLS);
|
||||
server_.enableSSL(std::move(policy));
|
||||
}
|
||||
|
||||
void enableSSL(trantor::TLSPolicyPtr policy)
|
||||
{
|
||||
server_.enableSSL(std::move(policy));
|
||||
}
|
||||
|
||||
const trantor::InetAddress &address() const
|
||||
|
|
|
@ -58,12 +58,8 @@ void ListenerManager::addListener(
|
|||
bool useOldTLS,
|
||||
const std::vector<std::pair<std::string, std::string>> &sslConfCmds)
|
||||
{
|
||||
#ifndef OpenSSL_FOUND
|
||||
if (useSSL)
|
||||
{
|
||||
if (useSSL && !utils::supportsTls())
|
||||
LOG_ERROR << "Can't use SSL without OpenSSL found in your system";
|
||||
}
|
||||
#endif
|
||||
listeners_.emplace_back(
|
||||
ip, port, useSSL, certFile, keyFile, useOldTLS, sslConfCmds);
|
||||
}
|
||||
|
@ -83,15 +79,9 @@ void ListenerManager::createListeners(
|
|||
const WebSocketNewAsyncCallback &webSocketCallback,
|
||||
const ConnectionCallback &connectionCallback,
|
||||
size_t connectionTimeout,
|
||||
#ifdef OpenSSL_FOUND
|
||||
const std::string &globalCertFile,
|
||||
const std::string &globalKeyFile,
|
||||
const std::vector<std::pair<std::string, std::string>> &sslConfCmds,
|
||||
#else
|
||||
const std::string & /*globalCertFile*/,
|
||||
const std::string & /*globalKeyFile*/,
|
||||
const std::vector<std::pair<std::string, std::string>> & /*sslConfCmds*/,
|
||||
#endif
|
||||
const std::vector<trantor::EventLoop *> &ioLoops,
|
||||
const std::vector<std::function<HttpResponsePtr(const HttpRequestPtr &)>>
|
||||
&syncAdvices,
|
||||
|
@ -132,9 +122,8 @@ void ListenerManager::createListeners(
|
|||
syncAdvices,
|
||||
preSendingAdvices);
|
||||
|
||||
if (listener.useSSL_)
|
||||
if (listener.useSSL_ && utils::supportsTls())
|
||||
{
|
||||
#ifdef OpenSSL_FOUND
|
||||
auto cert = listener.certFile_;
|
||||
auto key = listener.keyFile_;
|
||||
if (cert.empty())
|
||||
|
@ -152,8 +141,10 @@ void ListenerManager::createListeners(
|
|||
std::copy(listener.sslConfCmds_.begin(),
|
||||
listener.sslConfCmds_.end(),
|
||||
std::back_inserter(cmds));
|
||||
serverPtr->enableSSL(cert, key, listener.useOldTLS_, cmds);
|
||||
#endif
|
||||
auto policy =
|
||||
trantor::TLSPolicy::defaultServerPolicy(cert, key);
|
||||
policy->setConfCmds(cmds).setUseOldTLS(listener.useOldTLS_);
|
||||
serverPtr->enableSSL(std::move(policy));
|
||||
}
|
||||
serverPtr->setHttpAsyncCallback(httpCallback);
|
||||
serverPtr->setNewWebsocketCallback(webSocketCallback);
|
||||
|
@ -179,9 +170,8 @@ void ListenerManager::createListeners(
|
|||
"drogon",
|
||||
syncAdvices,
|
||||
preSendingAdvices);
|
||||
if (listener.useSSL_)
|
||||
if (listener.useSSL_ && utils::supportsTls())
|
||||
{
|
||||
#ifdef OpenSSL_FOUND
|
||||
auto cert = listener.certFile_;
|
||||
auto key = listener.keyFile_;
|
||||
if (cert.empty())
|
||||
|
@ -196,11 +186,10 @@ void ListenerManager::createListeners(
|
|||
exit(1);
|
||||
}
|
||||
auto cmds = sslConfCmds;
|
||||
std::copy(listener.sslConfCmds_.begin(),
|
||||
listener.sslConfCmds_.end(),
|
||||
std::back_inserter(cmds));
|
||||
serverPtr->enableSSL(cert, key, listener.useOldTLS_, cmds);
|
||||
#endif
|
||||
auto policy =
|
||||
trantor::TLSPolicy::defaultServerPolicy(cert, key);
|
||||
policy->setConfCmds(cmds).setUseOldTLS(listener.useOldTLS_);
|
||||
serverPtr->enableSSL(std::move(policy));
|
||||
}
|
||||
serverPtr->setIoLoops(ioLoops);
|
||||
serverPtr->setHttpAsyncCallback(httpCallback);
|
||||
|
|
|
@ -15,13 +15,8 @@
|
|||
#include <drogon/utils/Utilities.h>
|
||||
#include "filesystem.h"
|
||||
#include <trantor/utils/Logger.h>
|
||||
#include <trantor/utils/Utilities.h>
|
||||
#include <drogon/config.h>
|
||||
#ifdef OpenSSL_FOUND
|
||||
#include <openssl/md5.h>
|
||||
#include <openssl/rand.h>
|
||||
#else
|
||||
#include "ssl_funcs/Md5.h"
|
||||
#endif
|
||||
#ifdef USE_BROTLI
|
||||
#include <brotli/decode.h>
|
||||
#include <brotli/encode.h>
|
||||
|
@ -30,26 +25,23 @@
|
|||
#include <Rpc.h>
|
||||
#include <direct.h>
|
||||
#include <io.h>
|
||||
#include <ntsecapi.h>
|
||||
#else
|
||||
#include <uuid.h>
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#include <zlib.h>
|
||||
#include <iomanip>
|
||||
#include <mutex>
|
||||
#include <sstream>
|
||||
#include <stack>
|
||||
#include <string>
|
||||
#include <thread>
|
||||
#include <mutex>
|
||||
#include <algorithm>
|
||||
#include <array>
|
||||
#include <locale>
|
||||
#include <clocale>
|
||||
#include <cctype>
|
||||
#include <cstdlib>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#ifdef _WIN32
|
||||
|
@ -1144,27 +1136,27 @@ std::string brotliDecompress(const char * /*data*/, const size_t /*ndata*/)
|
|||
|
||||
std::string getMd5(const char *data, const size_t dataLen)
|
||||
{
|
||||
#if defined(OpenSSL_FOUND) && OPENSSL_VERSION_MAJOR < 3
|
||||
MD5_CTX c;
|
||||
unsigned char md5[16] = {0};
|
||||
MD5_Init(&c);
|
||||
MD5_Update(&c, data, dataLen);
|
||||
MD5_Final(md5, &c);
|
||||
return utils::binaryStringToHex(md5, 16);
|
||||
#elif defined(OpenSSL_FOUND)
|
||||
unsigned char md5[16] = {0};
|
||||
const EVP_MD *md = EVP_get_digestbyname("md5");
|
||||
assert(md != nullptr);
|
||||
return trantor::utils::toHexString(trantor::utils::md5(data, dataLen));
|
||||
}
|
||||
|
||||
EVP_MD_CTX *mdctx = EVP_MD_CTX_new();
|
||||
EVP_DigestInit_ex2(mdctx, md, NULL);
|
||||
EVP_DigestUpdate(mdctx, data, dataLen);
|
||||
EVP_DigestFinal_ex(mdctx, md5, NULL);
|
||||
EVP_MD_CTX_free(mdctx);
|
||||
return utils::binaryStringToHex(md5, 16);
|
||||
#else
|
||||
return Md5Encode::encode(data, dataLen);
|
||||
#endif
|
||||
std::string getSha1(const char *data, const size_t dataLen)
|
||||
{
|
||||
return trantor::utils::toHexString(trantor::utils::sha1(data, dataLen));
|
||||
}
|
||||
|
||||
std::string getSha256(const char *data, const size_t dataLen)
|
||||
{
|
||||
return trantor::utils::toHexString(trantor::utils::sha256(data, dataLen));
|
||||
}
|
||||
|
||||
std::string getSha3(const char *data, const size_t dataLen)
|
||||
{
|
||||
return trantor::utils::toHexString(trantor::utils::sha3(data, dataLen));
|
||||
}
|
||||
|
||||
std::string getBlake2b(const char *data, const size_t dataLen)
|
||||
{
|
||||
return trantor::utils::toHexString(trantor::utils::blake2b(data, dataLen));
|
||||
}
|
||||
|
||||
void replaceAll(std::string &s, const std::string &from, const std::string &to)
|
||||
|
@ -1177,48 +1169,50 @@ void replaceAll(std::string &s, const std::string &from, const std::string &to)
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Generates `size` random bytes from the systems random source and
|
||||
* stores them into `ptr`.
|
||||
*/
|
||||
static bool systemRandomBytes(void *ptr, size_t size)
|
||||
bool supportsTls() noexcept
|
||||
{
|
||||
#if defined(__BSD__) || defined(__APPLE__)
|
||||
arc4random_buf(ptr, size);
|
||||
return true;
|
||||
#elif defined(__linux__) && \
|
||||
((defined(__GLIBC__) && \
|
||||
(__GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 25))))
|
||||
return getentropy(ptr, size) != -1;
|
||||
#elif defined(_WIN32) // Windows
|
||||
return RtlGenRandom(ptr, (ULONG)size);
|
||||
#elif defined(__unix__) || defined(__HAIKU__)
|
||||
// fallback to /dev/urandom for other/old UNIX
|
||||
thread_local std::unique_ptr<FILE, std::function<void(FILE *)> > fptr(
|
||||
fopen("/dev/urandom", "rb"), [](FILE *ptr) {
|
||||
if (ptr != nullptr)
|
||||
fclose(ptr);
|
||||
});
|
||||
if (fptr == nullptr)
|
||||
{
|
||||
LOG_FATAL << "Failed to open /dev/urandom for randomness";
|
||||
abort();
|
||||
}
|
||||
if (fread(ptr, 1, size, fptr.get()) != 0)
|
||||
return true;
|
||||
#endif
|
||||
return false;
|
||||
return trantor::utils::tlsBackend() != "None";
|
||||
}
|
||||
|
||||
bool secureRandomBytes(void *ptr, size_t size)
|
||||
{
|
||||
#ifdef OpenSSL_FOUND
|
||||
if (RAND_bytes((unsigned char *)ptr, (int)size) == 0)
|
||||
return true;
|
||||
#endif
|
||||
if (systemRandomBytes(ptr, size))
|
||||
return true;
|
||||
return false;
|
||||
return trantor::utils::secureRandomBytes(ptr, size);
|
||||
}
|
||||
|
||||
std::string secureRandomString(size_t size)
|
||||
{
|
||||
if (size == 0)
|
||||
return std::string();
|
||||
|
||||
std::string ret(size, 0);
|
||||
const string_view chars =
|
||||
"0123456789"
|
||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
||||
"abcdefghijklmnopqrstuvwxyz"
|
||||
"+-";
|
||||
assert(chars.size() == 64);
|
||||
|
||||
trantor::utils::Hash256 hash;
|
||||
// batch up to 32 bytes of random data for efficiency. Calling
|
||||
// secureRandomBytes can be expensive.
|
||||
auto randByte = [&hash]() {
|
||||
static size_t i = 0;
|
||||
if (i == 0)
|
||||
{
|
||||
bool ok = trantor::utils::secureRandomBytes(&hash, sizeof(hash));
|
||||
if (!ok)
|
||||
throw std::runtime_error(
|
||||
"Failed to generate random bytes for secureRandomString");
|
||||
}
|
||||
unsigned char *hashBytes = reinterpret_cast<unsigned char *>(&hash);
|
||||
auto ret = hashBytes[i];
|
||||
i = (i + 1) % sizeof(hash);
|
||||
return ret;
|
||||
};
|
||||
|
||||
for (size_t i = 0; i < size; ++i)
|
||||
ret[i] = chars[randByte() % 64];
|
||||
return ret;
|
||||
}
|
||||
|
||||
namespace internal
|
||||
|
|
|
@ -22,11 +22,7 @@
|
|||
#include <drogon/utils/Utilities.h>
|
||||
#include <drogon/config.h>
|
||||
#include <trantor/net/InetAddress.h>
|
||||
#ifdef OpenSSL_FOUND
|
||||
#include <openssl/sha.h>
|
||||
#else
|
||||
#include "ssl_funcs/Sha1.h"
|
||||
#endif
|
||||
#include <trantor/utils/Utilities.h>
|
||||
|
||||
using namespace drogon;
|
||||
using namespace trantor;
|
||||
|
@ -55,7 +51,11 @@ void WebSocketClientImpl::createTcpClient()
|
|||
std::make_shared<trantor::TcpClient>(loop_, serverAddr_, "httpClient");
|
||||
if (useSSL_)
|
||||
{
|
||||
tcpClientPtr_->enableSSL(useOldTLS_, validateCert_, domain_);
|
||||
auto policy = trantor::TLSPolicy::defaultClientPolicy();
|
||||
policy->setUseOldTLS(useOldTLS_)
|
||||
.setValidate(validateCert_)
|
||||
.setHostname(domain_);
|
||||
tcpClientPtr_->enableSSL(std::move(policy));
|
||||
}
|
||||
auto thisPtr = shared_from_this();
|
||||
std::weak_ptr<WebSocketClientImpl> weakPtr = thisPtr;
|
||||
|
@ -130,11 +130,11 @@ void WebSocketClientImpl::connectToServerInLoop()
|
|||
|
||||
auto wsKey = wsKey_;
|
||||
wsKey.append("258EAFA5-E914-47DA-95CA-C5AB0DC85B11");
|
||||
unsigned char accKey[SHA_DIGEST_LENGTH];
|
||||
SHA1(reinterpret_cast<const unsigned char *>(wsKey.c_str()),
|
||||
wsKey.length(),
|
||||
accKey);
|
||||
wsAccept_ = utils::base64Encode(accKey, SHA_DIGEST_LENGTH);
|
||||
unsigned char accKey[20];
|
||||
static_assert(sizeof(accKey) == sizeof(trantor::utils::Hash160));
|
||||
auto sha1 = trantor::utils::sha1(wsKey);
|
||||
memcpy(accKey, &sha1, sizeof(sha1));
|
||||
wsAccept_ = utils::base64Encode(accKey, 20);
|
||||
|
||||
upgradeRequest_->addHeader("Sec-WebSocket-Key", wsKey_);
|
||||
// upgradeRequest_->addHeader("Sec-WebSocket-Version","13");
|
||||
|
|
|
@ -21,11 +21,7 @@
|
|||
#include <drogon/HttpFilter.h>
|
||||
#include <drogon/WebSocketController.h>
|
||||
#include <drogon/config.h>
|
||||
#ifdef OpenSSL_FOUND
|
||||
#include <openssl/sha.h>
|
||||
#else
|
||||
#include "ssl_funcs/Sha1.h"
|
||||
#endif
|
||||
#include <trantor/utils/Utilities.h>
|
||||
using namespace drogon;
|
||||
|
||||
void WebsocketControllersRouter::registerWebSocketController(
|
||||
|
@ -338,11 +334,10 @@ void WebsocketControllersRouter::doControllerHandler(
|
|||
const WebSocketConnectionImplPtr &wsConnPtr)
|
||||
{
|
||||
wsKey.append("258EAFA5-E914-47DA-95CA-C5AB0DC85B11");
|
||||
unsigned char accKey[SHA_DIGEST_LENGTH];
|
||||
SHA1(reinterpret_cast<const unsigned char *>(wsKey.c_str()),
|
||||
wsKey.length(),
|
||||
accKey);
|
||||
auto base64Key = utils::base64Encode(accKey, SHA_DIGEST_LENGTH);
|
||||
unsigned char accKey[20];
|
||||
auto sha1 = trantor::utils::sha1(wsKey.c_str(), wsKey.length());
|
||||
memcpy(accKey, &sha1, sizeof(sha1));
|
||||
auto base64Key = utils::base64Encode(accKey, sizeof(accKey));
|
||||
auto resp = HttpResponse::newHttpResponse();
|
||||
resp->setStatusCode(k101SwitchingProtocols);
|
||||
resp->addHeader("Upgrade", "websocket");
|
||||
|
|
|
@ -1,351 +0,0 @@
|
|||
/**
|
||||
*
|
||||
* Md5.cc
|
||||
* An Tao
|
||||
*
|
||||
* Copyright 2018, An Tao. All rights reserved.
|
||||
* https://github.com/an-tao/drogon
|
||||
* Use of this source code is governed by a MIT license
|
||||
* that can be found in the License file.
|
||||
*
|
||||
* Drogon
|
||||
*
|
||||
*/
|
||||
|
||||
#include "Md5.h"
|
||||
#include <math.h>
|
||||
#include <string.h>
|
||||
|
||||
const uint32_t Md5Encode::kA = 0x67452301;
|
||||
const uint32_t Md5Encode::kB = 0xefcdab89;
|
||||
const uint32_t Md5Encode::kC = 0x98badcfe;
|
||||
const uint32_t Md5Encode::kD = 0x10325476;
|
||||
|
||||
const uint64_t Md5Encode::tiNumInteger = 4294967296;
|
||||
|
||||
// function: CycleMoveLeft
|
||||
// @param srcNum: the number to be moved left
|
||||
// @param bitNumToMove: the number of bit of moving
|
||||
// @return result after moving
|
||||
uint32_t Md5Encode::cycleMoveLeft(uint32_t srcNum, int bitNumToMove)
|
||||
{
|
||||
uint32_t srcNum1 = srcNum;
|
||||
uint32_t srcNum2 = srcNum;
|
||||
if (0 >= bitNumToMove)
|
||||
{
|
||||
return srcNum;
|
||||
}
|
||||
return ((srcNum1 << bitNumToMove) | (srcNum2 >> (32 - bitNumToMove)));
|
||||
}
|
||||
|
||||
// function: FillData
|
||||
// @param inDataPtr: input data
|
||||
// @param dataByteLen: length of input data
|
||||
// @param outDataPtr: output data
|
||||
// return : length of output data
|
||||
uint32_t Md5Encode::fillData(const char *inDataPtr,
|
||||
int dataByteLen,
|
||||
char **outDataPtr)
|
||||
{
|
||||
int bitNum = dataByteLen * BIT_OF_BYTE;
|
||||
// int grop_num = bitNum / BIT_OF_GROUP;
|
||||
int modBitNum = bitNum % BIT_OF_GROUP;
|
||||
int bitNeedFill = 0;
|
||||
if (modBitNum >= (BIT_OF_GROUP - SRC_DATA_LEN))
|
||||
{
|
||||
bitNeedFill = (BIT_OF_GROUP - modBitNum);
|
||||
bitNeedFill += (BIT_OF_GROUP - SRC_DATA_LEN);
|
||||
}
|
||||
else
|
||||
{
|
||||
bitNeedFill = (BIT_OF_GROUP - SRC_DATA_LEN) - modBitNum;
|
||||
}
|
||||
int allBit = bitNum + bitNeedFill;
|
||||
if (0 < bitNeedFill)
|
||||
{
|
||||
*outDataPtr =
|
||||
new char[allBit / BIT_OF_BYTE + SRC_DATA_LEN / BIT_OF_BYTE];
|
||||
memset(*outDataPtr,
|
||||
0,
|
||||
allBit / BIT_OF_BYTE + SRC_DATA_LEN / BIT_OF_BYTE);
|
||||
// copy data
|
||||
memcpy(*outDataPtr, inDataPtr, dataByteLen);
|
||||
// fill rest data
|
||||
unsigned char *tmp = reinterpret_cast<unsigned char *>(*outDataPtr);
|
||||
tmp += dataByteLen;
|
||||
// fill 1 and 0
|
||||
*tmp = 0x80;
|
||||
// fill origin data len
|
||||
unsigned long long *originNum =
|
||||
(unsigned long long *)((*outDataPtr) + ((allBit / BIT_OF_BYTE)));
|
||||
*originNum = dataByteLen * BIT_OF_BYTE;
|
||||
}
|
||||
return (allBit / BIT_OF_BYTE + SRC_DATA_LEN / BIT_OF_BYTE);
|
||||
}
|
||||
|
||||
void Md5Encode::roundF(char *data512Ptr, ParamDynamic ¶m)
|
||||
{
|
||||
uint32_t *M = reinterpret_cast<uint32_t *>(data512Ptr);
|
||||
int s[] = {7, 12, 17, 22};
|
||||
for (int i = 0; i < 16; ++i)
|
||||
{
|
||||
uint64_t ti = tiNumInteger * fabs(sin(i + 1));
|
||||
if (i % 4 == 0)
|
||||
{
|
||||
FF(param.ua_, param.ub_, param.uc_, param.ud_, M[i], s[i % 4], ti);
|
||||
}
|
||||
else if (i % 4 == 1)
|
||||
{
|
||||
FF(param.ud_, param.ua_, param.ub_, param.uc_, M[i], s[i % 4], ti);
|
||||
}
|
||||
else if (i % 4 == 2)
|
||||
{
|
||||
FF(param.uc_, param.ud_, param.ua_, param.ub_, M[i], s[i % 4], ti);
|
||||
}
|
||||
else if (i % 4 == 3)
|
||||
{
|
||||
FF(param.ub_, param.uc_, param.ud_, param.ua_, M[i], s[i % 4], ti);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Md5Encode::roundG(char *data512Ptr, ParamDynamic ¶m)
|
||||
{
|
||||
uint32_t *M = reinterpret_cast<uint32_t *>(data512Ptr);
|
||||
int s[] = {5, 9, 14, 20};
|
||||
for (int i = 0; i < 16; ++i)
|
||||
{
|
||||
auto sss = sin(i + 1 + 16);
|
||||
uint64_t ti = tiNumInteger * fabs(sss);
|
||||
int index = (i * 5 + 1) % 16;
|
||||
if (i % 4 == 0)
|
||||
{
|
||||
GG(param.ua_,
|
||||
param.ub_,
|
||||
param.uc_,
|
||||
param.ud_,
|
||||
M[index],
|
||||
s[i % 4],
|
||||
ti);
|
||||
}
|
||||
else if (i % 4 == 1)
|
||||
{
|
||||
GG(param.ud_,
|
||||
param.ua_,
|
||||
param.ub_,
|
||||
param.uc_,
|
||||
M[index],
|
||||
s[i % 4],
|
||||
ti);
|
||||
}
|
||||
else if (i % 4 == 2)
|
||||
{
|
||||
GG(param.uc_,
|
||||
param.ud_,
|
||||
param.ua_,
|
||||
param.ub_,
|
||||
M[index],
|
||||
s[i % 4],
|
||||
ti);
|
||||
}
|
||||
else if (i % 4 == 3)
|
||||
{
|
||||
GG(param.ub_,
|
||||
param.uc_,
|
||||
param.ud_,
|
||||
param.ua_,
|
||||
M[index],
|
||||
s[i % 4],
|
||||
ti);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Md5Encode::roundH(char *data512Ptr, ParamDynamic ¶m)
|
||||
{
|
||||
uint32_t *M = reinterpret_cast<uint32_t *>(data512Ptr);
|
||||
int s[] = {4, 11, 16, 23};
|
||||
for (int i = 0; i < 16; ++i)
|
||||
{
|
||||
uint64_t ti = tiNumInteger * fabs(sin(i + 1 + 32));
|
||||
int index = (i * 3 + 5) % 16;
|
||||
if (i % 4 == 0)
|
||||
{
|
||||
HH(param.ua_,
|
||||
param.ub_,
|
||||
param.uc_,
|
||||
param.ud_,
|
||||
M[index],
|
||||
s[i % 4],
|
||||
ti);
|
||||
}
|
||||
else if (i % 4 == 1)
|
||||
{
|
||||
HH(param.ud_,
|
||||
param.ua_,
|
||||
param.ub_,
|
||||
param.uc_,
|
||||
M[index],
|
||||
s[i % 4],
|
||||
ti);
|
||||
}
|
||||
else if (i % 4 == 2)
|
||||
{
|
||||
HH(param.uc_,
|
||||
param.ud_,
|
||||
param.ua_,
|
||||
param.ub_,
|
||||
M[index],
|
||||
s[i % 4],
|
||||
ti);
|
||||
}
|
||||
else if (i % 4 == 3)
|
||||
{
|
||||
HH(param.ub_,
|
||||
param.uc_,
|
||||
param.ud_,
|
||||
param.ua_,
|
||||
M[index],
|
||||
s[i % 4],
|
||||
ti);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Md5Encode::roundI(char *data512Ptr, ParamDynamic ¶m)
|
||||
{
|
||||
uint32_t *M = reinterpret_cast<uint32_t *>(data512Ptr);
|
||||
int s[] = {6, 10, 15, 21};
|
||||
for (int i = 0; i < 16; ++i)
|
||||
{
|
||||
uint64_t ti = tiNumInteger * fabs(sin(i + 1 + 48));
|
||||
int index = (i * 7 + 0) % 16;
|
||||
if (i % 4 == 0)
|
||||
{
|
||||
II(param.ua_,
|
||||
param.ub_,
|
||||
param.uc_,
|
||||
param.ud_,
|
||||
M[index],
|
||||
s[i % 4],
|
||||
ti);
|
||||
}
|
||||
else if (i % 4 == 1)
|
||||
{
|
||||
II(param.ud_,
|
||||
param.ua_,
|
||||
param.ub_,
|
||||
param.uc_,
|
||||
M[index],
|
||||
s[i % 4],
|
||||
ti);
|
||||
}
|
||||
else if (i % 4 == 2)
|
||||
{
|
||||
II(param.uc_,
|
||||
param.ud_,
|
||||
param.ua_,
|
||||
param.ub_,
|
||||
M[index],
|
||||
s[i % 4],
|
||||
ti);
|
||||
}
|
||||
else if (i % 4 == 3)
|
||||
{
|
||||
II(param.ub_,
|
||||
param.uc_,
|
||||
param.ud_,
|
||||
param.ua_,
|
||||
M[index],
|
||||
s[i % 4],
|
||||
ti);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Md5Encode::rotationCalculate(char *data512Ptr, ParamDynamic ¶m)
|
||||
{
|
||||
if (nullptr == data512Ptr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
roundF(data512Ptr, param);
|
||||
roundG(data512Ptr, param);
|
||||
roundH(data512Ptr, param);
|
||||
roundI(data512Ptr, param);
|
||||
param.ua_ = param.va_last_ + param.ua_;
|
||||
param.ub_ = param.vb_last_ + param.ub_;
|
||||
param.uc_ = param.vc_last_ + param.uc_;
|
||||
param.ud_ = param.vd_last_ + param.ud_;
|
||||
|
||||
param.va_last_ = param.ua_;
|
||||
param.vb_last_ = param.ub_;
|
||||
param.vc_last_ = param.uc_;
|
||||
param.vd_last_ = param.ud_;
|
||||
}
|
||||
|
||||
// Convert to hex format string
|
||||
std::string Md5Encode::getHexStr(uint32_t numStr)
|
||||
{
|
||||
std::string hexstr = "";
|
||||
char szch[] = {'0',
|
||||
'1',
|
||||
'2',
|
||||
'3',
|
||||
'4',
|
||||
'5',
|
||||
'6',
|
||||
'7',
|
||||
'8',
|
||||
'9',
|
||||
'A',
|
||||
'B',
|
||||
'C',
|
||||
'D',
|
||||
'E',
|
||||
'F'};
|
||||
unsigned char *tmptr = (unsigned char *)&numStr;
|
||||
int len = sizeof(numStr);
|
||||
for (int i = 0; i < len; ++i)
|
||||
{
|
||||
unsigned char ch = tmptr[i] & 0xF0;
|
||||
ch = ch >> 4;
|
||||
hexstr.append(1, szch[ch]);
|
||||
ch = tmptr[i] & 0x0F;
|
||||
hexstr.append(1, szch[ch]);
|
||||
}
|
||||
return hexstr;
|
||||
}
|
||||
|
||||
// function: Encode
|
||||
// @param srcInfo: the string to be encoded.
|
||||
// return : the string after encoding
|
||||
std::string Md5Encode::encode(const char *data, const size_t dataLen)
|
||||
{
|
||||
ParamDynamic param;
|
||||
param.ua_ = kA;
|
||||
param.ub_ = kB;
|
||||
param.uc_ = kC;
|
||||
param.ud_ = kD;
|
||||
param.va_last_ = kA;
|
||||
param.vb_last_ = kB;
|
||||
param.vc_last_ = kC;
|
||||
param.vd_last_ = kD;
|
||||
|
||||
std::string result;
|
||||
char *outDataPtr = nullptr;
|
||||
int totalByte = fillData(data, dataLen, &outDataPtr);
|
||||
|
||||
for (int i = 0; i < totalByte / (BIT_OF_GROUP / BIT_OF_BYTE); ++i)
|
||||
{
|
||||
char *dataBitOfGroup = outDataPtr;
|
||||
dataBitOfGroup += i * (BIT_OF_GROUP / BIT_OF_BYTE);
|
||||
rotationCalculate(dataBitOfGroup, param);
|
||||
}
|
||||
delete[] outDataPtr, outDataPtr = nullptr;
|
||||
result.append(getHexStr(param.ua_));
|
||||
result.append(getHexStr(param.ub_));
|
||||
result.append(getHexStr(param.uc_));
|
||||
result.append(getHexStr(param.ud_));
|
||||
return result;
|
||||
}
|
|
@ -1,81 +0,0 @@
|
|||
/*
|
||||
*******************************************************
|
||||
* brief: md5 encryption
|
||||
* author: Monkey.Knight
|
||||
*******************************************************
|
||||
*/
|
||||
|
||||
/**
|
||||
*
|
||||
* Md5.h
|
||||
* An Tao
|
||||
*
|
||||
* Copyright 2018, An Tao. All rights reserved.
|
||||
* https://github.com/an-tao/drogon
|
||||
* Use of this source code is governed by a MIT license
|
||||
* that can be found in the License file.
|
||||
*
|
||||
* Drogon
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <cstdint>
|
||||
|
||||
#define BIT_OF_BYTE 8
|
||||
#define BIT_OF_GROUP 512
|
||||
#define SRC_DATA_LEN 64
|
||||
|
||||
#define DEF_F(X, Y, Z) ((((X) & (Y)) | ((~X) & (Z))))
|
||||
#define DEF_G(X, Y, Z) (((X) & (Z)) | ((Y) & (~Z)))
|
||||
#define DEF_H(X, Y, Z) ((X) ^ (Y) ^ (Z))
|
||||
#define DEF_I(X, Y, Z) ((Y) ^ ((X) | (~Z)))
|
||||
|
||||
#define FF(a, b, c, d, Mj, s, ti) \
|
||||
(a = b + cycleMoveLeft((a + DEF_F(b, c, d) + Mj + ti), s))
|
||||
#define GG(a, b, c, d, Mj, s, ti) \
|
||||
(a = b + cycleMoveLeft((a + DEF_G(b, c, d) + Mj + ti), s))
|
||||
#define HH(a, b, c, d, Mj, s, ti) \
|
||||
(a = b + cycleMoveLeft((a + DEF_H(b, c, d) + Mj + ti), s))
|
||||
#define II(a, b, c, d, Mj, s, ti) \
|
||||
(a = b + cycleMoveLeft((a + DEF_I(b, c, d) + Mj + ti), s))
|
||||
|
||||
class Md5Encode
|
||||
{
|
||||
public:
|
||||
struct ParamDynamic
|
||||
{
|
||||
uint32_t ua_;
|
||||
uint32_t ub_;
|
||||
uint32_t uc_;
|
||||
uint32_t ud_;
|
||||
uint32_t va_last_;
|
||||
uint32_t vb_last_;
|
||||
uint32_t vc_last_;
|
||||
uint32_t vd_last_;
|
||||
};
|
||||
|
||||
public:
|
||||
static std::string encode(const char *data, const size_t dataLen);
|
||||
|
||||
protected:
|
||||
static uint32_t cycleMoveLeft(uint32_t srcNum, int bitNumToMove);
|
||||
static void roundF(char *data512Ptr, ParamDynamic ¶m);
|
||||
static void roundG(char *data512Ptr, ParamDynamic ¶m);
|
||||
static void roundH(char *data512Ptr, ParamDynamic ¶m);
|
||||
static void roundI(char *data512Ptr, ParamDynamic ¶m);
|
||||
static void rotationCalculate(char *data512Ptr, ParamDynamic ¶m);
|
||||
static std::string getHexStr(uint32_t numStr);
|
||||
static uint32_t fillData(const char *inDataPtr,
|
||||
int dataByteLen,
|
||||
char **outDataPtr);
|
||||
|
||||
private:
|
||||
static const uint32_t kA;
|
||||
static const uint32_t kB;
|
||||
static const uint32_t kC;
|
||||
static const uint32_t kD;
|
||||
static const uint64_t tiNumInteger;
|
||||
};
|
|
@ -1,159 +0,0 @@
|
|||
/**
|
||||
*
|
||||
* Sha1.cc
|
||||
* An Tao
|
||||
*
|
||||
* Copyright 2018, An Tao. All rights reserved.
|
||||
* https://github.com/an-tao/drogon
|
||||
* Use of this source code is governed by a MIT license
|
||||
* that can be found in the License file.
|
||||
*
|
||||
* Drogon
|
||||
*
|
||||
*/
|
||||
|
||||
#include "Sha1.h"
|
||||
#include <string.h>
|
||||
|
||||
static inline unsigned int fromBigEndian(unsigned int v)
|
||||
{
|
||||
return ((v & 0xff) << 24) | ((v & 0xff00) << 8) | ((v & 0xff0000) >> 8) |
|
||||
((v & 0xff000000) >> 24);
|
||||
}
|
||||
|
||||
static void writeBigEndian64(unsigned char *p, unsigned int v)
|
||||
{
|
||||
memset(p, 0, 8);
|
||||
memcpy(p, &v, 4);
|
||||
int i = 0;
|
||||
for (i = 0; i < 4; ++i)
|
||||
{
|
||||
unsigned char t = p[i];
|
||||
p[i] = p[7 - i];
|
||||
p[7 - i] = t;
|
||||
}
|
||||
}
|
||||
|
||||
static inline unsigned int leftRoll(unsigned int v, int n)
|
||||
{
|
||||
return (v << n) | (v >> (32 - n));
|
||||
}
|
||||
|
||||
unsigned char *SHA1(const unsigned char *dataIn,
|
||||
size_t dataLen,
|
||||
unsigned char *dataOut)
|
||||
{
|
||||
unsigned char *pbytes = (unsigned char *)dataIn;
|
||||
unsigned int nbyte = (unsigned int)dataLen;
|
||||
|
||||
static unsigned int words[80];
|
||||
unsigned int H[5] = {
|
||||
0x67452301, 0xEFCDAB89, 0x98BADCFE, 0x10325476, 0xC3D2E1F0};
|
||||
unsigned int f, k, temp, bitlen[2], word;
|
||||
unsigned int i, j, index, p1, p2, maxlen;
|
||||
unsigned char spec[4] = {0};
|
||||
i = nbyte % 4;
|
||||
|
||||
p1 = nbyte - i;
|
||||
spec[i] = 1 << 7;
|
||||
while (i--)
|
||||
{
|
||||
spec[i] = pbytes[p1 + i];
|
||||
}
|
||||
|
||||
maxlen = (nbyte + 1) % 64;
|
||||
if (maxlen <= 56)
|
||||
{
|
||||
maxlen = (nbyte + 1) - maxlen + 64;
|
||||
}
|
||||
else
|
||||
{
|
||||
maxlen = (nbyte + 1) - maxlen + 128;
|
||||
}
|
||||
p2 = maxlen - 8;
|
||||
writeBigEndian64((unsigned char *)bitlen, nbyte * 8);
|
||||
|
||||
for (j = 0; j < maxlen; j += 64)
|
||||
{
|
||||
unsigned int a, b, c, d, e;
|
||||
a = H[0];
|
||||
b = H[1];
|
||||
c = H[2];
|
||||
d = H[3];
|
||||
e = H[4];
|
||||
for (i = 0; i < 80; ++i)
|
||||
{
|
||||
if (i < 16)
|
||||
{
|
||||
index = j + (i << 2);
|
||||
if (index < p1)
|
||||
{
|
||||
word = *((unsigned int *)(pbytes + index));
|
||||
}
|
||||
else if (index == p1)
|
||||
{
|
||||
word = *(unsigned int *)spec;
|
||||
}
|
||||
else if (index < p2)
|
||||
{
|
||||
word = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
word = (index < maxlen - 4) ? bitlen[0] : bitlen[1];
|
||||
}
|
||||
words[i] = fromBigEndian(word);
|
||||
}
|
||||
else
|
||||
{
|
||||
words[i] = leftRoll(words[i - 3] ^ words[i - 8] ^
|
||||
words[i - 14] ^ words[i - 16],
|
||||
1);
|
||||
}
|
||||
if (i < 20)
|
||||
{
|
||||
f = (b & c) | ((~b) & d);
|
||||
k = 0x5A827999;
|
||||
}
|
||||
else if (i < 40)
|
||||
{
|
||||
f = b ^ c ^ d;
|
||||
k = 0x6ED9EBA1;
|
||||
}
|
||||
else if (i < 60)
|
||||
{
|
||||
f = (b & c) | (b & d) | (c & d);
|
||||
k = 0x8F1BBCDC;
|
||||
}
|
||||
else
|
||||
{
|
||||
f = b ^ c ^ d;
|
||||
k = 0xCA62C1D6;
|
||||
}
|
||||
temp = leftRoll(a, 5) + f + e + k + words[i];
|
||||
e = d;
|
||||
d = c;
|
||||
c = leftRoll(b, 30);
|
||||
b = a;
|
||||
a = temp;
|
||||
}
|
||||
H[0] += a;
|
||||
H[1] += b;
|
||||
H[2] += c;
|
||||
H[3] += d;
|
||||
H[4] += e;
|
||||
}
|
||||
int ct = 0;
|
||||
for (i = 0; i < 5; ++i)
|
||||
{
|
||||
unsigned char buf[4] = {0};
|
||||
memcpy(buf, &(H[i]), 4);
|
||||
for (int r = 3; r >= 0; r--)
|
||||
{
|
||||
dataOut[ct] = buf[r];
|
||||
++ct;
|
||||
}
|
||||
}
|
||||
|
||||
return dataOut;
|
||||
}
|
|
@ -1,23 +0,0 @@
|
|||
/**
|
||||
*
|
||||
* Sha1.h
|
||||
* An Tao
|
||||
*
|
||||
* Copyright 2018, An Tao. All rights reserved.
|
||||
* https://github.com/an-tao/drogon
|
||||
* Use of this source code is governed by a MIT license
|
||||
* that can be found in the License file.
|
||||
*
|
||||
* Drogon
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#define SHA_DIGEST_LENGTH 20
|
||||
|
||||
unsigned char *SHA1(const unsigned char *dataIn,
|
||||
size_t dataLen,
|
||||
unsigned char *dataOut);
|
|
@ -17,7 +17,6 @@ set(UNITTEST_SOURCES
|
|||
unittests/OStringStreamTest.cc
|
||||
unittests/PubSubServiceUnittest.cc
|
||||
unittests/Sha1Test.cc
|
||||
../src/ssl_funcs/Sha1.cc
|
||||
unittests/FileTypeTest.cc
|
||||
unittests/DrObjectTest.cc
|
||||
unittests/HttpFullDateTest.cc
|
||||
|
@ -99,7 +98,8 @@ if (BUILD_CTL)
|
|||
${CMAKE_CURRENT_SOURCE_DIR}/integration_test/server/test.md
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/integration_test/server/index.html.gz
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/integration_test/server/中文.txt
|
||||
${PROJECT_SOURCE_DIR}/trantor/trantor/tests/server.pem
|
||||
${PROJECT_SOURCE_DIR}/trantor/trantor/tests/server.crt
|
||||
${PROJECT_SOURCE_DIR}/trantor/trantor/tests/server.key
|
||||
$<TARGET_FILE_DIR:integration_test_server>)
|
||||
add_custom_command(
|
||||
TARGET integration_test_server POST_BUILD
|
||||
|
|
|
@ -49,9 +49,10 @@ void doTest(const HttpClientPtr &client, std::shared_ptr<test::Case> TEST_CTX)
|
|||
req->setMethod(drogon::Get);
|
||||
req->setPath("/");
|
||||
std::promise<int> waitCookie;
|
||||
bool haveCert = false;
|
||||
auto f = waitCookie.get_future();
|
||||
client->sendRequest(req,
|
||||
[client, &waitCookie, TEST_CTX](
|
||||
[client, &waitCookie, &haveCert, TEST_CTX](
|
||||
ReqResult result, const HttpResponsePtr &resp) {
|
||||
REQUIRE(result == ReqResult::Ok);
|
||||
|
||||
|
@ -61,8 +62,11 @@ void doTest(const HttpClientPtr &client, std::shared_ptr<test::Case> TEST_CTX)
|
|||
sessionID = id;
|
||||
client->addCookie(id);
|
||||
waitCookie.set_value(1);
|
||||
|
||||
haveCert = resp->peerCertificate() != nullptr;
|
||||
});
|
||||
f.get();
|
||||
CHECK(haveCert == client->secure());
|
||||
}
|
||||
else
|
||||
client->addCookie(sessionID);
|
||||
|
@ -1067,7 +1071,7 @@ void doTest(const HttpClientPtr &client, std::shared_ptr<test::Case> TEST_CTX)
|
|||
}
|
||||
catch (const std::exception &e)
|
||||
{
|
||||
FAIL("Unexpected exception, what()" + std::string(e.what()));
|
||||
FAIL("Unexpected exception, what(): " + std::string(e.what()));
|
||||
}
|
||||
|
||||
// Test Coroutine exception
|
||||
|
@ -1080,7 +1084,7 @@ void doTest(const HttpClientPtr &client, std::shared_ptr<test::Case> TEST_CTX)
|
|||
}
|
||||
catch (const std::exception &e)
|
||||
{
|
||||
FAIL("Unexpected exception, what()" + std::string(e.what()));
|
||||
FAIL("Unexpected exception, what(): " + std::string(e.what()));
|
||||
}
|
||||
|
||||
// Test Coroutine exception with co_return
|
||||
|
@ -1093,7 +1097,7 @@ void doTest(const HttpClientPtr &client, std::shared_ptr<test::Case> TEST_CTX)
|
|||
}
|
||||
catch (const std::exception &e)
|
||||
{
|
||||
FAIL("Unexpected exception, what()" + std::string(e.what()));
|
||||
FAIL("Unexpected exception, what(): " + std::string(e.what()));
|
||||
}
|
||||
|
||||
// Test coroutine filter
|
||||
|
@ -1110,7 +1114,7 @@ void doTest(const HttpClientPtr &client, std::shared_ptr<test::Case> TEST_CTX)
|
|||
}
|
||||
catch (const std::exception &e)
|
||||
{
|
||||
FAIL("Unexpected exception, what()" + std::string(e.what()));
|
||||
FAIL("Unexpected exception, what(): " + std::string(e.what()));
|
||||
}
|
||||
|
||||
// Test coroutine handler with parameters
|
||||
|
@ -1124,7 +1128,7 @@ void doTest(const HttpClientPtr &client, std::shared_ptr<test::Case> TEST_CTX)
|
|||
}
|
||||
catch (const std::exception &e)
|
||||
{
|
||||
FAIL("Unexpected exception, what()" + std::string(e.what()));
|
||||
FAIL("Unexpected exception, what(): " + std::string(e.what()));
|
||||
}
|
||||
try
|
||||
{
|
||||
|
@ -1136,7 +1140,7 @@ void doTest(const HttpClientPtr &client, std::shared_ptr<test::Case> TEST_CTX)
|
|||
}
|
||||
catch (const std::exception &e)
|
||||
{
|
||||
FAIL("Unexpected exception, what()" + std::string(e.what()));
|
||||
FAIL("Unexpected exception, what(): " + std::string(e.what()));
|
||||
}
|
||||
});
|
||||
#endif
|
||||
|
|
|
@ -158,7 +158,7 @@ int main()
|
|||
if (app().supportSSL())
|
||||
{
|
||||
drogon::app()
|
||||
.setSSLFiles("server.pem", "server.pem")
|
||||
.setSSLFiles("server.crt", "server.key")
|
||||
.addListener("0.0.0.0", 8849, true);
|
||||
}
|
||||
// Class function example
|
||||
|
|
|
@ -60,7 +60,7 @@ int main(int argc, char **argv)
|
|||
|
||||
std::thread thr([&]() {
|
||||
app()
|
||||
.setSSLFiles("server.pem", "server.pem")
|
||||
.setSSLFiles("server.crt", "server.key")
|
||||
.addListener("0.0.0.0", 8855, true)
|
||||
.enableSession();
|
||||
app().getLoop()->queueInLoop([&p1]() { p1.set_value(); });
|
||||
|
|
|
@ -1,17 +1,12 @@
|
|||
#include "../../lib/src/ssl_funcs/Sha1.h"
|
||||
#include <drogon/utils/Utilities.h>
|
||||
#include <drogon/drogon_test.h>
|
||||
#include <string>
|
||||
|
||||
DROGON_TEST(SHA1Test)
|
||||
{
|
||||
unsigned char in[] =
|
||||
char in[] =
|
||||
"1234567890123456789012345678901234567890123456789012345"
|
||||
"678901234567890123456789012345678901234567890";
|
||||
unsigned char out[SHA_DIGEST_LENGTH] = {0};
|
||||
SHA1(in, strlen((const char *)in), out);
|
||||
std::string outStr;
|
||||
outStr.resize(SHA_DIGEST_LENGTH * 2);
|
||||
for (int i = 0; i < SHA_DIGEST_LENGTH; ++i)
|
||||
sprintf((char *)(outStr.data() + i * 2), "%02x", out[i]);
|
||||
CHECK(outStr == "fecfd28bbc9345891a66d7c1b8ff46e60192d284");
|
||||
auto str = drogon::utils::getSha1(in, strlen((const char *)in));
|
||||
CHECK(str == "FECFD28BBC9345891A66D7C1B8FF46E60192D284");
|
||||
}
|
2
trantor
2
trantor
|
@ -1 +1 @@
|
|||
Subproject commit b5709ef4d43fa18b6d23090bbc54975fd1974c3d
|
||||
Subproject commit 8e224d11b2bd6966e435cf5b75fe99973663cb1b
|
Loading…
Reference in New Issue