Files
wlan-cloud-ucentralgw/src/AP_WS_Server.cpp
2022-07-27 09:59:57 -07:00

154 lines
5.1 KiB
C++

//
// License type: BSD 3-Clause License
// License copy: https://github.com/Telecominfraproject/wlan-cloud-ucentralgw/blob/master/LICENSE
//
// Created by Stephane Bourque on 2021-03-04.
// Arilia Wireless Inc.
//
#include "Poco/Net/HTTPHeaderStream.h"
#include "Poco/JSON/Array.h"
#include "Poco/Net/Context.h"
#include "AP_WS_Server.h"
#include "ConfigurationCache.h"
#include "TelemetryStream.h"
namespace OpenWifi {
void AP_WS_RequestHandler::handleRequest(Poco::Net::HTTPServerRequest &request,
Poco::Net::HTTPServerResponse &response) {
try {
new AP_WS_Connection(request,response);
} catch (...) {
Logger_.warning("Exception during WS creation");
}
};
bool AP_WS_Server::ValidateCertificate(const std::string & ConnectionId, const Poco::Crypto::X509Certificate & Certificate) {
if(IsCertOk()) {
if(!Certificate.issuedBy(*IssuerCert_)) {
poco_warning(Logger(),fmt::format("CERTIFICATE({}): issuer mismatch. Local='{}' Incoming='{}'", ConnectionId, IssuerCert_->issuerName(), Certificate.issuerName()));
return false;
}
return true;
}
return false;
}
int AP_WS_Server::Start() {
for(const auto & Svr : ConfigServersList_ ) {
Logger().notice(fmt::format("Starting: {}:{} Keyfile:{} CertFile: {}", Svr.Address(),
Svr.Port(), Svr.KeyFile(), Svr.CertFile()));
Svr.LogCert(Logger());
if (!Svr.RootCA().empty())
Svr.LogCas(Logger());
if (!IsCertOk()) {
IssuerCert_ = std::make_unique<Poco::Crypto::X509Certificate>(Svr.IssuerCertFile());
Logger().information(
fmt::format("Certificate Issuer Name:{}", IssuerCert_->issuerName()));
}
Poco::Net::Context::Params P;
P.verificationMode = Poco::Net::Context::VERIFY_ONCE;
P.verificationDepth = 9;
P.loadDefaultCAs = Svr.RootCA().empty();
P.cipherList = "ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH";
P.dhUse2048Bits = true;
P.caLocation = Svr.Cas();
auto Context = Poco::AutoPtr<Poco::Net::Context>(new Poco::Net::Context(Poco::Net::Context::TLS_SERVER_USE, P));
Context->enableExtendedCertificateVerification(false);
if(!Svr.KeyFilePassword().empty()) {
auto PassphraseHandler = Poco::SharedPtr<MyPrivateKeyPassphraseHandler>( new MyPrivateKeyPassphraseHandler(Svr.KeyFilePassword(),Logger()));
Poco::Net::SSLManager::instance().initializeServer(PassphraseHandler, nullptr,Context);
}
Poco::Crypto::X509Certificate Cert(Svr.CertFile());
Poco::Crypto::X509Certificate Root(Svr.RootCA());
Context->useCertificate(Cert);
Context->addChainCertificate(Root);
Context->addCertificateAuthority(Root);
Poco::Crypto::X509Certificate Issuing(Svr.IssuerCertFile());
Context->addChainCertificate(Issuing);
Context->addCertificateAuthority(Issuing);
Poco::Crypto::RSAKey Key("", Svr.KeyFile(), Svr.KeyFilePassword());
Context->usePrivateKey(Key);
Context->enableSessionCache();
Context->setSessionCacheSize(0);
Context->setSessionTimeout(60);
Context->enableExtendedCertificateVerification(false);
Context->disableStatelessSessionResumption();
auto WebServerHttpParams = new Poco::Net::HTTPServerParams;
WebServerHttpParams->setMaxThreads(50);
WebServerHttpParams->setMaxQueued(200);
WebServerHttpParams->setKeepAlive(true);
WebServerHttpParams->setName("ws:ap_dispatch");
if (Svr.Address() == "*") {
Poco::Net::IPAddress Addr(Poco::Net::IPAddress::wildcard(
Poco::Net::Socket::supportsIPv6() ? Poco::Net::AddressFamily::IPv6
: Poco::Net::AddressFamily::IPv4));
Poco::Net::SocketAddress SockAddr(Addr, Svr.Port());
auto NewWebServer = std::make_unique<Poco::Net::HTTPServer>(
new AP_WS_RequestHandlerFactory(Logger()), DeviceConnectionPool_, Poco::Net::SecureServerSocket(SockAddr, Svr.Backlog(), Context), WebServerHttpParams);
WebServers_.push_back(std::move(NewWebServer));
} else {
Poco::Net::IPAddress Addr(Svr.Address());
Poco::Net::SocketAddress SockAddr(Addr, Svr.Port());
auto NewWebServer = std::make_unique<Poco::Net::HTTPServer>(
new AP_WS_RequestHandlerFactory(Logger()), DeviceConnectionPool_, Poco::Net::SecureServerSocket(SockAddr, Svr.Backlog(), Context), WebServerHttpParams);
WebServers_.push_back(std::move(NewWebServer));
}
}
for(auto &server:WebServers_) {
server->start();
}
ReactorThread_.start(Reactor_);
Reactor_pool_ = std::make_unique<AP_WS_ReactorThreadPool>();
Reactor_pool_->Start();
auto ProvString = MicroService::instance().ConfigGetString("autoprovisioning.process","default");
if(ProvString!="default") {
auto Tokens = Poco::StringTokenizer(ProvString, ",");
for (const auto &i : Tokens) {
if (i == "prov")
LookAtProvisioning_ = true;
else
UseDefaultConfig_ = true;
}
} else {
UseDefaultConfig_ = true;
}
SimulatorId_ = MicroService::instance().ConfigGetString("simulatorid","");
SimulatorEnabled_ = !SimulatorId_.empty();
Utils::SetThreadName(ReactorThread_,"dev:react:head");
return 0;
}
void AP_WS_Server::Stop() {
Logger().notice("Stopping reactors...");
for(auto &server:WebServers_) {
server->stopAll();
}
Reactor_pool_->Stop();
Reactor_.stop();
ReactorThread_.join();
}
} //namespace