From b950694753dca3da3ce6b64c0c675e6b769171ab Mon Sep 17 00:00:00 2001 From: stephb9959 Date: Fri, 1 Sep 2023 09:26:06 -0700 Subject: [PATCH 01/46] https://telecominfraproject.atlassian.net/browse/WIFI-12868 Signed-off-by: stephb9959 --- src/framework/RESTAPI_Handler.h | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/framework/RESTAPI_Handler.h b/src/framework/RESTAPI_Handler.h index a7ed681..b74d6e7 100644 --- a/src/framework/RESTAPI_Handler.h +++ b/src/framework/RESTAPI_Handler.h @@ -574,6 +574,16 @@ namespace OpenWifi { Poco::JSON::Stringifier::stringify(Object, Answer); } + inline void ReturnObject(const std::vector &Strings) { + Poco::JSON::Array Arr; + for(const auto &String:Strings) { + Arr.add(String); + } + std::ostringstream os; + Arr.stringify(os); + return ReturnRawJSON(os.str()); + } + inline void ReturnRawJSON(const std::string &json_doc) { PrepareResponse(); if (Request != nullptr) { From 5cc00a2e7280e10d3a1ed09b6a46577bfa4e541b Mon Sep 17 00:00:00 2001 From: stephb9959 Date: Mon, 11 Sep 2023 14:43:30 -0700 Subject: [PATCH 02/46] https://telecominfraproject.atlassian.net/browse/WIFI-7831 Signed-off-by: stephb9959 --- CMakeLists.txt | 2 +- build | 2 +- src/Daemon.cpp | 5 +- src/OpenRoamin_GlobalReach.cpp | 85 +++++++++++++++++++ src/OpenRoamin_GlobalReach.h | 37 +++++++++ src/RESTObjects/RESTAPI_ProvObjects.cpp | 56 +++++++++++++ src/RESTObjects/RESTAPI_ProvObjects.h | 25 ++++++ src/StorageService.cpp | 26 ++++++ src/StorageService.h | 44 +++++----- src/framework/ow_constants.h | 1 + src/framework/utils.cpp | 104 ++++++++++++++++++++++++ src/framework/utils.h | 2 + src/storage/storage_glblraccounts.cpp | 85 +++++++++++++++++++ src/storage/storage_glblraccounts.h | 31 +++++++ src/storage/storage_glblrcerts.cpp | 76 +++++++++++++++++ src/storage/storage_glblrcerts.h | 37 +++++++++ 16 files changed, 596 insertions(+), 22 deletions(-) create mode 100644 src/OpenRoamin_GlobalReach.cpp create mode 100644 src/OpenRoamin_GlobalReach.h create mode 100644 src/storage/storage_glblraccounts.cpp create mode 100644 src/storage/storage_glblraccounts.h create mode 100644 src/storage/storage_glblrcerts.cpp create mode 100644 src/storage/storage_glblrcerts.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 707f627..6790ea5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -209,7 +209,7 @@ add_executable(owprov src/ProvWebSocketClient.cpp src/ProvWebSocketClient.h src/Tasks/VenueRebooter.h src/Tasks/VenueUpgrade.h src/sdks/SDK_fms.cpp src/sdks/SDK_fms.h - src/RESTAPI/RESTAPI_overrides_handler.cpp src/RESTAPI/RESTAPI_overrides_handler.h) + src/RESTAPI/RESTAPI_overrides_handler.cpp src/RESTAPI/RESTAPI_overrides_handler.h src/OpenRoamin_GlobalReach.cpp src/OpenRoamin_GlobalReach.h src/storage/storage_glblraccounts.cpp src/storage/storage_glblraccounts.h src/storage/storage_glblrcerts.cpp src/storage/storage_glblrcerts.h) target_link_libraries(owprov PUBLIC ${Poco_LIBRARIES} diff --git a/build b/build index bf0d87a..3cacc0b 100644 --- a/build +++ b/build @@ -1 +1 @@ -4 \ No newline at end of file +12 \ No newline at end of file diff --git a/src/Daemon.cpp b/src/Daemon.cpp index 7c50216..55a3938 100644 --- a/src/Daemon.cpp +++ b/src/Daemon.cpp @@ -23,6 +23,7 @@ #include "UI_Prov_WebSocketNotifications.h" #include "framework/ConfigurationValidator.h" #include "framework/UI_WebSocketClientServer.h" +#include "OpenRoamin_GlobalReach.h" namespace OpenWifi { class Daemon *Daemon::instance_ = nullptr; @@ -35,7 +36,9 @@ namespace OpenWifi { ConfigurationValidator(), SerialNumberCache(), AutoDiscovery(), JobController(), UI_WebSocketClientServer(), FindCountryFromIP(), - Signup(), FileDownloader()}); + Signup(), FileDownloader(), + OpenRoaming_GlobalReach() + }); } return instance_; } diff --git a/src/OpenRoamin_GlobalReach.cpp b/src/OpenRoamin_GlobalReach.cpp new file mode 100644 index 0000000..d5fa293 --- /dev/null +++ b/src/OpenRoamin_GlobalReach.cpp @@ -0,0 +1,85 @@ +// +// Created by stephane bourque on 2023-09-11. +// + +#include "OpenRoamin_GlobalReach.h" + +namespace OpenWifi { + + int OpenRoaming_GlobalReach::Start() { + poco_information(Logger(), "Starting..."); + return 0; + } + + void OpenRoaming_GlobalReach::Stop() { + poco_information(Logger(), "Stopping..."); + poco_information(Logger(), "Stopped..."); + } + + bool OpenRoaming_GlobalReach::GetAccountInfo(const std::string &AccountName, ProvObjects::GLBLRAccountInfo &Account) { +/* Poco::URI URI{"https://config.openro.am/v1/config"}; + + std::string Path(URI.getPathAndQuery()); + + Poco::Net::HTTPRequest Request(Poco::Net::HTTPRequest::HTTP_GET, Path, + Poco::Net::HTTPMessage::HTTP_1_1); + + Request.add("Authorization", "Bearer " + BearerToken); + + Poco::Net::HTTPSClientSession Session(URI.getHost(), URI.getPort()); + Session.setTimeout(Poco::Timespan(10000, 10000)); + + Session.sendRequest(Request); + + Poco::Net::HTTPResponse Response; + std::istream &is = Session.receiveResponse(Response); + Poco::JSON::Parser P; + Result= P.parse(is).extract(); + + std::cout << Response.getStatus() << " : " ; + Result->stringify(std::cout); + std::cout << std::endl; + */ + return true; + } + + bool OpenRoaming_GlobalReach::CreateRadsecCertificate(const std::string &AccountName, ProvObjects::GLBLRCertificateInfo &NewCertificate) { +/* + Poco::URI URI{"https://config.openro.am/v1/radsec/issue"}; + + std::string Path(URI.getPathAndQuery()); + + Poco::Net::HTTPRequest Request(Poco::Net::HTTPRequest::HTTP_POST, Path, + Poco::Net::HTTPMessage::HTTP_1_1); + + Request.add("Authorization", "Bearer " + BearerToken); + + Poco::Net::HTTPSClientSession Session(URI.getHost(), URI.getPort()); + Session.setTimeout(Poco::Timespan(10000, 10000)); + + std::ostringstream os; + Body.stringify(os); + Request.setContentType("application/json"); + Request.setContentLength(os.str().size()); + + auto &body = Session.sendRequest(Request); + body << os.str(); + + Poco::Net::HTTPResponse Response; + std::istream &is = Session.receiveResponse(Response); + Poco::JSON::Parser P; + Result= P.parse(is).extract(); + + std::cout << Response.getStatus() << " : " ; + Result->stringify(std::cout); + std::cout << std::endl; +*/ + return true; + } + + bool OpenRoaming_GlobalReach::GetRadsecCertificate(const std::string &AccountName, std::string &CertificateId, + ProvObjects::GLBLRCertificateInfo &NewCertificate) { + return true; + } + +} // OpenWifi \ No newline at end of file diff --git a/src/OpenRoamin_GlobalReach.h b/src/OpenRoamin_GlobalReach.h new file mode 100644 index 0000000..767329c --- /dev/null +++ b/src/OpenRoamin_GlobalReach.h @@ -0,0 +1,37 @@ +// +// Created by stephane bourque on 2023-09-11. +// + +#pragma once + +#include "framework/SubSystemServer.h" +#include "Poco/JSON/Object.h" +#include "RESTObjects/RESTAPI_ProvObjects.h" + +namespace OpenWifi { + + class OpenRoaming_GlobalReach : public SubSystemServer { + public: + static auto instance() { + static auto instance_ = new OpenRoaming_GlobalReach; + return instance_; + } + + int Start() override; + void Stop() override; + bool GetAccountInfo(const std::string &AccountName, ProvObjects::GLBLRAccountInfo &Account); + bool CreateRadsecCertificate(const std::string &AccountName, ProvObjects::GLBLRCertificateInfo &NewCertificate); + bool GetRadsecCertificate(const std::string &AccountName, std::string & CertificateId, ProvObjects::GLBLRCertificateInfo &NewCertificate); + + private: + std::string CreateJWTToken(const std::string &AccountName); + + OpenRoaming_GlobalReach() noexcept + : SubSystemServer("OpenRoaming_GlobalReach", "GLBL-REACH", "globalreach") { + } + }; + + inline auto OpenRoaming_GlobalReach() { return OpenRoaming_GlobalReach::instance(); } + +} // OpenWifi + diff --git a/src/RESTObjects/RESTAPI_ProvObjects.cpp b/src/RESTObjects/RESTAPI_ProvObjects.cpp index 533d0f4..bafd9ac 100644 --- a/src/RESTObjects/RESTAPI_ProvObjects.cpp +++ b/src/RESTObjects/RESTAPI_ProvObjects.cpp @@ -1194,4 +1194,60 @@ namespace OpenWifi::ProvObjects { return false; } + void GLBLRAccountInfo::to_json(Poco::JSON::Object &Obj) const { + info.to_json(Obj); + field_to_json(Obj, "privateKey", privateKey); + field_to_json(Obj, "country", country); + field_to_json(Obj, "province", province); + field_to_json(Obj, "city", city); + field_to_json(Obj, "organization", organization); + field_to_json(Obj, "commonName", commonName); + } + + bool GLBLRAccountInfo::from_json(const Poco::JSON::Object::Ptr &Obj) { + try { + info.from_json(Obj); + field_from_json(Obj, "privateKey", privateKey); + field_from_json(Obj, "country", country); + field_from_json(Obj, "province", province); + field_from_json(Obj, "city", city); + field_from_json(Obj, "organization", organization); + field_from_json(Obj, "commonName", commonName); + return true; + } catch (const Poco::Exception &E) { + + } + return false; + } + + void GLBLRCertificateInfo::to_json(Poco::JSON::Object &Obj) const { + field_to_json(Obj, "id", id); + field_to_json(Obj, "name", name); + field_to_json(Obj, "accountId", accountId); + field_to_json(Obj, "csr", csr); + field_to_json(Obj, "certificate", certificate); + field_to_json(Obj, "certificateChain", certificateChain); + field_to_json(Obj, "certificateId", certificateId); + field_to_json(Obj, "expiresAt", expiresAt); + field_to_json(Obj, "created", created); + } + + bool GLBLRCertificateInfo::from_json(const Poco::JSON::Object::Ptr &Obj) { + try { + field_from_json(Obj, "id", id); + field_from_json(Obj, "name", name); + field_from_json(Obj, "accountId", accountId); + field_from_json(Obj, "csr", csr); + field_from_json(Obj, "certificate", certificate); + field_from_json(Obj, "certificateChain", certificateChain); + field_from_json(Obj, "certificateId", certificateId); + field_from_json(Obj, "expiresAt", expiresAt); + field_from_json(Obj, "created", created); + return true; + } catch (const Poco::Exception &E) { + + } + return false; + } + } // namespace OpenWifi::ProvObjects diff --git a/src/RESTObjects/RESTAPI_ProvObjects.h b/src/RESTObjects/RESTAPI_ProvObjects.h index 9f4edf3..ffdc136 100644 --- a/src/RESTObjects/RESTAPI_ProvObjects.h +++ b/src/RESTObjects/RESTAPI_ProvObjects.h @@ -746,4 +746,29 @@ namespace OpenWifi::ProvObjects { bool CreateObjectInfo(const Poco::JSON::Object::Ptr &O, const SecurityObjects::UserInfo &U, ObjectInfo &I); bool CreateObjectInfo(const SecurityObjects::UserInfo &U, ObjectInfo &I); + + struct GLBLRAccountInfo { + ObjectInfo info; + std::string privateKey; + std::string country, province, city, organization, commonName; + + void to_json(Poco::JSON::Object &Obj) const; + bool from_json(const Poco::JSON::Object::Ptr &Obj); + }; + + struct GLBLRCertificateInfo { + std::string id; + std::string name; + std::string accountId; + std::string csr; + std::string certificate; + std::string certificateChain; + std::string certificateId; + std::uint64_t expiresAt=0; + std::uint64_t created=0; + + void to_json(Poco::JSON::Object &Obj) const; + bool from_json(const Poco::JSON::Object::Ptr &Obj); + }; + }; // namespace OpenWifi::ProvObjects diff --git a/src/StorageService.cpp b/src/StorageService.cpp index fdec47a..1a1e193 100644 --- a/src/StorageService.cpp +++ b/src/StorageService.cpp @@ -39,6 +39,8 @@ namespace OpenWifi { OpLocationDB_ = std::make_unique(dbType_, *Pool_, Logger()); OpContactDB_ = std::make_unique(dbType_, *Pool_, Logger()); OverridesDB_ = std::make_unique(dbType_, *Pool_, Logger()); + GLBLRAccountInfoDB_ = std::make_unique(dbType_, *Pool_, Logger()); + GLBLRCertsDB_ = std::make_unique(dbType_, *Pool_, Logger()); EntityDB_->Create(); PolicyDB_->Create(); @@ -59,6 +61,8 @@ namespace OpenWifi { OpLocationDB_->Create(); OpContactDB_->Create(); OverridesDB_->Create(); + GLBLRAccountInfoDB_->Create(); + GLBLRCertsDB_->Create(); ExistFunc_[EntityDB_->Prefix()] = [=](const char *F, std::string &V) -> bool { return EntityDB_->Exists(F, V); @@ -117,6 +121,14 @@ namespace OpenWifi { ExistFunc_[OverridesDB_->Prefix()] = [=](const char *F, std::string &V) -> bool { return OverridesDB_->Exists(F, V); }; + ExistFunc_[GLBLRAccountInfoDB_->Prefix()] = [=](const char *F, std::string &V) -> bool { + return GLBLRAccountInfoDB_->Exists(F, V); + }; + ExistFunc_[GLBLRCertsDB_->Prefix()] = [=](const char *F, std::string &V) -> bool { + return GLBLRCertsDB_->Exists(F, V); + }; + + ExpandFunc_[EntityDB_->Prefix()] = [=](const char *F, std::string &V, std::string &Name, std::string &Description) -> bool { @@ -207,6 +219,20 @@ namespace OpenWifi { [[maybe_unused]] std::string &Name, [[maybe_unused]] std::string &Description) -> bool { return false; }; + ExpandFunc_[GLBLRAccountInfoDB_->Prefix()] = + [=]([[maybe_unused]] const char *F, [[maybe_unused]] std::string &V, + [[maybe_unused]] std::string &Name, + [[maybe_unused]] std::string &Description) -> bool { return false; }; + ExpandFunc_[OverridesDB_->Prefix()] = + [=]([[maybe_unused]] const char *F, [[maybe_unused]] std::string &V, + [[maybe_unused]] std::string &Name, + [[maybe_unused]] std::string &Description) -> bool { return false; }; + + ExpandFunc_[GLBLRCertsDB_->Prefix()] = + [=]([[maybe_unused]] const char *F, [[maybe_unused]] std::string &V, + [[maybe_unused]] std::string &Name, + [[maybe_unused]] std::string &Description) -> bool { return false; }; + InventoryDB_->InitializeSerialCache(); ConsistencyCheck(); diff --git a/src/StorageService.h b/src/StorageService.h index d160a13..adafaa8 100644 --- a/src/StorageService.h +++ b/src/StorageService.h @@ -28,6 +28,8 @@ #include "storage/storage_tags.h" #include "storage/storage_variables.h" #include "storage/storage_venue.h" +#include "storage/storage_glblraccounts.h" +#include "storage/storage_glblrcerts.h" #include "Poco/URI.h" #include "framework/ow_constants.h" @@ -47,25 +49,27 @@ namespace OpenWifi { typedef std::list ExpandedInUseList; typedef std::map ExpandedListMap; - OpenWifi::EntityDB &EntityDB() { return *EntityDB_; }; - OpenWifi::PolicyDB &PolicyDB() { return *PolicyDB_; }; - OpenWifi::VenueDB &VenueDB() { return *VenueDB_; }; - OpenWifi::LocationDB &LocationDB() { return *LocationDB_; }; - OpenWifi::ContactDB &ContactDB() { return *ContactDB_; }; - OpenWifi::InventoryDB &InventoryDB() { return *InventoryDB_; }; - OpenWifi::ManagementRoleDB &RolesDB() { return *RolesDB_; }; - OpenWifi::ConfigurationDB &ConfigurationDB() { return *ConfigurationDB_; }; - OpenWifi::TagsDictionaryDB &TagsDictionaryDB() { return *TagsDictionaryDB_; }; - OpenWifi::TagsObjectDB &TagsObjectDB() { return *TagsObjectDB_; }; - OpenWifi::MapDB &MapDB() { return *MapDB_; }; - OpenWifi::SignupDB &SignupDB() { return *SignupDB_; }; - OpenWifi::VariablesDB &VariablesDB() { return *VariablesDB_; }; - OpenWifi::OperatorDB &OperatorDB() { return *OperatorDB_; }; - OpenWifi::ServiceClassDB &ServiceClassDB() { return *ServiceClassDB_; }; - OpenWifi::SubscriberDeviceDB &SubscriberDeviceDB() { return *SubscriberDeviceDB_; }; - OpenWifi::OpLocationDB &OpLocationDB() { return *OpLocationDB_; }; - OpenWifi::OpContactDB &OpContactDB() { return *OpContactDB_; }; - OpenWifi::OverridesDB &OverridesDB() { return *OverridesDB_; }; + inline OpenWifi::EntityDB &EntityDB() { return *EntityDB_; }; + inline OpenWifi::PolicyDB &PolicyDB() { return *PolicyDB_; }; + inline OpenWifi::VenueDB &VenueDB() { return *VenueDB_; }; + inline OpenWifi::LocationDB &LocationDB() { return *LocationDB_; }; + inline OpenWifi::ContactDB &ContactDB() { return *ContactDB_; }; + inline OpenWifi::InventoryDB &InventoryDB() { return *InventoryDB_; }; + inline OpenWifi::ManagementRoleDB &RolesDB() { return *RolesDB_; }; + inline OpenWifi::ConfigurationDB &ConfigurationDB() { return *ConfigurationDB_; }; + inline OpenWifi::TagsDictionaryDB &TagsDictionaryDB() { return *TagsDictionaryDB_; }; + inline OpenWifi::TagsObjectDB &TagsObjectDB() { return *TagsObjectDB_; }; + inline OpenWifi::MapDB &MapDB() { return *MapDB_; }; + inline OpenWifi::SignupDB &SignupDB() { return *SignupDB_; }; + inline OpenWifi::VariablesDB &VariablesDB() { return *VariablesDB_; }; + inline OpenWifi::OperatorDB &OperatorDB() { return *OperatorDB_; }; + inline OpenWifi::ServiceClassDB &ServiceClassDB() { return *ServiceClassDB_; }; + inline OpenWifi::SubscriberDeviceDB &SubscriberDeviceDB() { return *SubscriberDeviceDB_; }; + inline OpenWifi::OpLocationDB &OpLocationDB() { return *OpLocationDB_; }; + inline OpenWifi::OpContactDB &OpContactDB() { return *OpContactDB_; }; + inline OpenWifi::OverridesDB &OverridesDB() { return *OverridesDB_; }; + inline OpenWifi::GLBLRAccountInfoDB &GLBLRAccountInfoDB() { return *GLBLRAccountInfoDB_; } + inline OpenWifi::GLBLRCertsDB &GLBLRCertsDB() { return *GLBLRCertsDB_; } bool Validate(const Poco::URI::QueryParameters &P, RESTAPI::Errors::msg &Error); bool Validate(const Types::StringVec &P, std::string &Error); @@ -125,6 +129,8 @@ namespace OpenWifi { std::unique_ptr OpLocationDB_; std::unique_ptr OpContactDB_; std::unique_ptr OverridesDB_; + std::unique_ptr GLBLRAccountInfoDB_; + std::unique_ptr GLBLRCertsDB_; std::string DefaultOperator_; typedef std::function exist_func; diff --git a/src/framework/ow_constants.h b/src/framework/ow_constants.h index c1a1bf7..2d45a3d 100644 --- a/src/framework/ow_constants.h +++ b/src/framework/ow_constants.h @@ -40,6 +40,7 @@ namespace OpenWifi { }; } +#define DBGLINE std::cout << __LINE__ << ":" << __FILE__ << ", " << __func__ << std::endl; namespace OpenWifi::RESTAPI::Errors { struct msg { uint64_t err_num; diff --git a/src/framework/utils.cpp b/src/framework/utils.cpp index a0f4c11..c37ff64 100644 --- a/src/framework/utils.cpp +++ b/src/framework/utils.cpp @@ -3,6 +3,7 @@ // #include "Poco/Path.h" +#include "Poco/TemporaryFile.h" #include "framework/AppServiceRegistry.h" #include "framework/utils.h" @@ -608,4 +609,107 @@ namespace OpenWifi::Utils { return DT.timestamp().epochTime(); } + bool CreateX509CSR(const std::string &Country, const std::string &Province, const std::string &City, + const std::string &Organization, const std::string &CommonName, int bits ) { + int ret = 0; + RSA *r = nullptr; + BIGNUM *bne = nullptr; + + int nVersion = 0; + unsigned long e = RSA_F4; + + X509_REQ *x509_req = nullptr; + X509_NAME *x509_name = nullptr; + EVP_PKEY *pKey = nullptr; +// RSA *tem = nullptr; + BIO *out = nullptr; +// BIO *bio_err = nullptr; + + const char *szCountry = Country.c_str(); + const char *szProvince = Province.c_str(); + const char *szCity = City.c_str(); + const char *szOrganization = Organization.c_str(); + const char *szCommon = CommonName.c_str(); + + Poco::TemporaryFile CsrPath; + +// 1. generate rsa key + bne = BN_new(); + ret = BN_set_word(bne,e); + if(ret != 1){ + goto free_all; + } + + r = RSA_new(); + ret = RSA_generate_key_ex(r, bits, bne, nullptr); + if(ret != 1){ + goto free_all; + } + +// 2. set version of x509 req + x509_req = X509_REQ_new(); + ret = X509_REQ_set_version(x509_req, nVersion); + if (ret != 1){ + goto free_all; + } + +// 3. set subject of x509 req + x509_name = X509_REQ_get_subject_name(x509_req); + + ret = X509_NAME_add_entry_by_txt(x509_name,"C", MBSTRING_ASC, (const unsigned char*)szCountry, -1, -1, 0); + if (ret != 1){ + goto free_all; + } + + ret = X509_NAME_add_entry_by_txt(x509_name,"ST", MBSTRING_ASC, (const unsigned char*)szProvince, -1, -1, 0); + if (ret != 1){ + goto free_all; + } + + ret = X509_NAME_add_entry_by_txt(x509_name,"L", MBSTRING_ASC, (const unsigned char*)szCity, -1, -1, 0); + if (ret != 1){ + goto free_all; + } + + ret = X509_NAME_add_entry_by_txt(x509_name,"O", MBSTRING_ASC, (const unsigned char*)szOrganization, -1, -1, 0); + if (ret != 1){ + goto free_all; + } + + ret = X509_NAME_add_entry_by_txt(x509_name,"CN", MBSTRING_ASC, (const unsigned char*)szCommon, -1, -1, 0); + if (ret != 1){ + goto free_all; + } + +// 4. set public key of x509 req + pKey = EVP_PKEY_new(); + EVP_PKEY_assign_RSA(pKey, r); + r = nullptr; // will be free rsa when EVP_PKEY_free(pKey) + + ret = X509_REQ_set_pubkey(x509_req, pKey); + if (ret != 1){ + goto free_all; + } + +// 5. set sign key of x509 req + ret = X509_REQ_sign(x509_req, pKey, EVP_sha1()); // return x509_req->signature->length + if (ret <= 0){ + goto free_all; + } + + out = BIO_new_file(CsrPath.path().c_str(),"w"); + ret = PEM_write_bio_X509_REQ(out, x509_req); + +// 6. free + free_all: + X509_REQ_free(x509_req); + BIO_free_all(out); + + EVP_PKEY_free(pKey); + BN_free(bne); + + return (ret == 1); + + } + } // namespace OpenWifi::Utils diff --git a/src/framework/utils.h b/src/framework/utils.h index 3979dca..89ba52a 100644 --- a/src/framework/utils.h +++ b/src/framework/utils.h @@ -247,4 +247,6 @@ namespace OpenWifi::Utils { return count; } + bool CreateX509CSR(const std::string &Country, const std::string &Province, const std::string &City, + const std::string &Organization, const std::string &CommonName, int bits=2048); } // namespace OpenWifi::Utils diff --git a/src/storage/storage_glblraccounts.cpp b/src/storage/storage_glblraccounts.cpp new file mode 100644 index 0000000..7f616c3 --- /dev/null +++ b/src/storage/storage_glblraccounts.cpp @@ -0,0 +1,85 @@ +// +// Created by stephane bourque on 2023-09-11. +// + +#include "storage_glblraccounts.h" +#include +#include "framework/OpenWifiTypes.h" +#include "framework/RESTAPI_utils.h" + +#include "RESTObjects/RESTAPI_SecurityObjects.h" + +namespace OpenWifi { + + static ORM::FieldVec GLBLRAccountInfoDB_Fields{// object info + ORM::Field{"id", 64, true}, + ORM::Field{"name", ORM::FieldType::FT_TEXT}, + ORM::Field{"description", ORM::FieldType::FT_TEXT}, + ORM::Field{"notes", ORM::FieldType::FT_TEXT}, + ORM::Field{"created", ORM::FieldType::FT_BIGINT}, + ORM::Field{"modified", ORM::FieldType::FT_BIGINT}, + ORM::Field{"privateKey", ORM::FieldType::FT_TEXT}, + ORM::Field{"country", ORM::FieldType::FT_TEXT}, + ORM::Field{"province", ORM::FieldType::FT_TEXT}, + ORM::Field{"city", ORM::FieldType::FT_TEXT}, + ORM::Field{"organization", ORM::FieldType::FT_TEXT}, + ORM::Field{"commonName", ORM::FieldType::FT_TEXT} + }; + + static ORM::IndexVec GLBLRAccountInfoDB_Indexes{ + {std::string("glblr_name_index"), + ORM::IndexEntryVec{{std::string("name"), ORM::Indextype::ASC}}}}; + + GLBLRAccountInfoDB::GLBLRAccountInfoDB(OpenWifi::DBType T, Poco::Data::SessionPool &P, Poco::Logger &L) + : DB(T, "glblr_accts", GLBLRAccountInfoDB_Fields, GLBLRAccountInfoDB_Indexes, P, L, "glr") {} + + bool GLBLRAccountInfoDB::Upgrade([[maybe_unused]] uint32_t from, uint32_t &to) { + to = Version(); + std::vector Script{}; + + for (const auto &i : Script) { + try { + auto Session = Pool_.get(); + Session << i, Poco::Data::Keywords::now; + } catch (...) { + } + } + return true; + } + +} // namespace OpenWifi + +template <> +void ORM::DB::Convert( + const OpenWifi::GLBLRAccountsDBRecordType &In, OpenWifi::ProvObjects::GLBLRAccountInfo &Out) { + Out.info.id = In.get<0>(); + Out.info.name = In.get<1>(); + Out.info.description = In.get<2>(); + Out.info.notes = + OpenWifi::RESTAPI_utils::to_object_array(In.get<3>()); + Out.info.created = In.get<4>(); + Out.info.modified = In.get<5>(); + Out.privateKey =In.get<6>(); + Out.country = In.get<7>(); + Out.province = In.get<8>(); + Out.city = In.get<9>(); + Out.organization = In.get<10>(); + Out.commonName = In.get<11>(); +} + +template <> +void ORM::DB::Convert( + const OpenWifi::ProvObjects::GLBLRAccountInfo &In, OpenWifi::GLBLRAccountsDBRecordType &Out) { + Out.set<0>(In.info.id); + Out.set<1>(In.info.name); + Out.set<2>(In.info.description); + Out.set<3>(OpenWifi::RESTAPI_utils::to_string(In.info.notes)); + Out.set<4>(In.info.created); + Out.set<5>(In.info.modified); + Out.set<6>(In.privateKey); + Out.set<7>(In.country); + Out.set<8>(In.province); + Out.set<9>(In.city); + Out.set<10>(In.organization); + Out.set<11>(In.commonName); +} diff --git a/src/storage/storage_glblraccounts.h b/src/storage/storage_glblraccounts.h new file mode 100644 index 0000000..bc213c1 --- /dev/null +++ b/src/storage/storage_glblraccounts.h @@ -0,0 +1,31 @@ +// +// Created by stephane bourque on 2023-09-11. +// + + +#pragma once + +#include "RESTObjects/RESTAPI_ProvObjects.h" +#include "framework/orm.h" + +namespace OpenWifi { + + typedef Poco::Tuple + GLBLRAccountsDBRecordType; + + class GLBLRAccountInfoDB : public ORM::DB { + public: + GLBLRAccountInfoDB(OpenWifi::DBType T, Poco::Data::SessionPool &P, Poco::Logger &L); + virtual ~GLBLRAccountInfoDB(){}; + bool Upgrade(uint32_t from, uint32_t &to) override; + private: + + }; +} // namespace OpenWifi diff --git a/src/storage/storage_glblrcerts.cpp b/src/storage/storage_glblrcerts.cpp new file mode 100644 index 0000000..fe0900d --- /dev/null +++ b/src/storage/storage_glblrcerts.cpp @@ -0,0 +1,76 @@ +// +// Created by stephane bourque on 2023-09-11. +// + +#include "storage_glblrcerts.h" + +#include +#include "framework/OpenWifiTypes.h" +#include "framework/RESTAPI_utils.h" + +#include "RESTObjects/RESTAPI_SecurityObjects.h" + +namespace OpenWifi { + + static ORM::FieldVec GLBLRCertsDB_Fields{// object info + ORM::Field{"id", 64, true}, + ORM::Field{"name", ORM::FieldType::FT_TEXT}, + ORM::Field{"accountId", ORM::FieldType::FT_TEXT}, + ORM::Field{"csr", ORM::FieldType::FT_TEXT}, + ORM::Field{"certificate", ORM::FieldType::FT_TEXT}, + ORM::Field{"certificateChain", ORM::FieldType::FT_TEXT}, + ORM::Field{"certificateId", ORM::FieldType::FT_TEXT}, + ORM::Field{"expiresAt", ORM::FieldType::FT_BIGINT}, + ORM::Field{"created", ORM::FieldType::FT_BIGINT} + }; + + static ORM::IndexVec GLBLRCertsDB_Indexes{ + {std::string("glblr_cert_id_index"), + ORM::IndexEntryVec{{std::string("name"), ORM::Indextype::ASC}}}}; + + GLBLRCertsDB::GLBLRCertsDB(OpenWifi::DBType T, Poco::Data::SessionPool &P, Poco::Logger &L) + : DB(T, "glblr_certs", GLBLRCertsDB_Fields, GLBLRCertsDB_Indexes, P, L, "glc") {} + + bool GLBLRCertsDB::Upgrade([[maybe_unused]] uint32_t from, uint32_t &to) { + to = Version(); + std::vector Script{}; + + for (const auto &i : Script) { + try { + auto Session = Pool_.get(); + Session << i, Poco::Data::Keywords::now; + } catch (...) { + } + } + return true; + } + +} // namespace OpenWifi + +template <> +void ORM::DB::Convert( + const OpenWifi::GLBLRCertsDBRecordType &In, OpenWifi::ProvObjects::GLBLRCertificateInfo &Out) { + Out.id = In.get<0>(); + Out.name = In.get<1>(); + Out.accountId = In.get<2>(); + Out.csr = In.get<3>(); + Out.certificate = In.get<4>(); + Out.certificateChain = In.get<5>(); + Out.certificateId = In.get<6>(); + Out.expiresAt = In.get<7>(); + Out.created = In.get<8>(); +} + +template <> +void ORM::DB::Convert( + const OpenWifi::ProvObjects::GLBLRCertificateInfo &In, OpenWifi::GLBLRCertsDBRecordType &Out) { + Out.set<0>(In.id); + Out.set<1>(In.name); + Out.set<2>(In.accountId); + Out.set<3>(In.csr); + Out.set<4>(In.certificate); + Out.set<5>(In.certificateChain); + Out.set<6>(In.certificateId); + Out.set<7>(In.expiresAt); + Out.set<8>(In.created); +} diff --git a/src/storage/storage_glblrcerts.h b/src/storage/storage_glblrcerts.h new file mode 100644 index 0000000..da097bc --- /dev/null +++ b/src/storage/storage_glblrcerts.h @@ -0,0 +1,37 @@ +// +// Created by stephane bourque on 2023-09-11. +// + +// +// Created by stephane bourque on 2023-09-11. +// + + +#pragma once + +#include "RESTObjects/RESTAPI_ProvObjects.h" +#include "framework/orm.h" + +namespace OpenWifi { + + typedef Poco::Tuple< + std::string, + std::string, + std::string, + std::string, + std::string, + std::string, + std::string, + uint64_t, + uint64_t> + GLBLRCertsDBRecordType; + + class GLBLRCertsDB : public ORM::DB { + public: + GLBLRCertsDB(OpenWifi::DBType T, Poco::Data::SessionPool &P, Poco::Logger &L); + virtual ~GLBLRCertsDB(){}; + bool Upgrade(uint32_t from, uint32_t &to) override; + private: + + }; +} // namespace OpenWifi From 21f8742bd8b27d6341727697148bac4ebd1e5e0f Mon Sep 17 00:00:00 2001 From: stephb9959 Date: Mon, 11 Sep 2023 22:35:44 -0700 Subject: [PATCH 03/46] https://telecominfraproject.atlassian.net/browse/WIFI-7831 Signed-off-by: stephb9959 --- CMakeLists.txt | 2 +- build | 2 +- openapi/openroaming_globalreach.yaml | 399 ++++++++++++++++++ openapi/ow_or_ameriband.yaml | 268 ------------ src/OpenRoamin_GlobalReach.cpp | 14 +- .../RESTAPI_openroaming_gr_acct_handler.cpp | 120 ++++++ .../RESTAPI_openroaming_gr_acct_handler.h | 31 ++ .../RESTAPI_openroaming_gr_cert_handler.cpp | 25 ++ .../RESTAPI_openroaming_gr_cert_handler.h | 31 ++ ...STAPI_openroaming_gr_list_acct_handler.cpp | 20 + ...RESTAPI_openroaming_gr_list_acct_handler.h | 29 ++ ...STAPI_openroaming_gr_list_certificates.cpp | 27 ++ ...RESTAPI_openroaming_gr_list_certificates.h | 29 ++ src/RESTAPI/RESTAPI_routers.cpp | 12 +- src/RESTObjects/RESTAPI_ProvObjects.cpp | 2 + src/RESTObjects/RESTAPI_ProvObjects.h | 1 + src/framework/RESTAPI_Handler.h | 22 +- src/framework/ow_constants.h | 1 + src/framework/utils.cpp | 32 +- src/framework/utils.h | 3 +- src/storage/storage_glblraccounts.cpp | 7 +- src/storage/storage_glblraccounts.h | 1 + 22 files changed, 794 insertions(+), 284 deletions(-) create mode 100644 openapi/openroaming_globalreach.yaml delete mode 100644 openapi/ow_or_ameriband.yaml create mode 100644 src/RESTAPI/RESTAPI_openroaming_gr_acct_handler.cpp create mode 100644 src/RESTAPI/RESTAPI_openroaming_gr_acct_handler.h create mode 100644 src/RESTAPI/RESTAPI_openroaming_gr_cert_handler.cpp create mode 100644 src/RESTAPI/RESTAPI_openroaming_gr_cert_handler.h create mode 100644 src/RESTAPI/RESTAPI_openroaming_gr_list_acct_handler.cpp create mode 100644 src/RESTAPI/RESTAPI_openroaming_gr_list_acct_handler.h create mode 100644 src/RESTAPI/RESTAPI_openroaming_gr_list_certificates.cpp create mode 100644 src/RESTAPI/RESTAPI_openroaming_gr_list_certificates.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 6790ea5..1b813be 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -209,7 +209,7 @@ add_executable(owprov src/ProvWebSocketClient.cpp src/ProvWebSocketClient.h src/Tasks/VenueRebooter.h src/Tasks/VenueUpgrade.h src/sdks/SDK_fms.cpp src/sdks/SDK_fms.h - src/RESTAPI/RESTAPI_overrides_handler.cpp src/RESTAPI/RESTAPI_overrides_handler.h src/OpenRoamin_GlobalReach.cpp src/OpenRoamin_GlobalReach.h src/storage/storage_glblraccounts.cpp src/storage/storage_glblraccounts.h src/storage/storage_glblrcerts.cpp src/storage/storage_glblrcerts.h) + src/RESTAPI/RESTAPI_overrides_handler.cpp src/RESTAPI/RESTAPI_overrides_handler.h src/OpenRoamin_GlobalReach.cpp src/OpenRoamin_GlobalReach.h src/storage/storage_glblraccounts.cpp src/storage/storage_glblraccounts.h src/storage/storage_glblrcerts.cpp src/storage/storage_glblrcerts.h src/RESTAPI/RESTAPI_openroaming_gr_list_acct_handler.cpp src/RESTAPI/RESTAPI_openroaming_gr_list_acct_handler.h src/RESTAPI/RESTAPI_openroaming_gr_acct_handler.cpp src/RESTAPI/RESTAPI_openroaming_gr_acct_handler.h src/RESTAPI/RESTAPI_openroaming_gr_list_certificates.cpp src/RESTAPI/RESTAPI_openroaming_gr_list_certificates.h src/RESTAPI/RESTAPI_openroaming_gr_cert_handler.cpp src/RESTAPI/RESTAPI_openroaming_gr_cert_handler.h) target_link_libraries(owprov PUBLIC ${Poco_LIBRARIES} diff --git a/build b/build index 3cacc0b..2edeafb 100644 --- a/build +++ b/build @@ -1 +1 @@ -12 \ No newline at end of file +20 \ No newline at end of file diff --git a/openapi/openroaming_globalreach.yaml b/openapi/openroaming_globalreach.yaml new file mode 100644 index 0000000..9e9b5ff --- /dev/null +++ b/openapi/openroaming_globalreach.yaml @@ -0,0 +1,399 @@ +openapi: 3.0.1 +info: + title: OpenWiFi Provisioning Model + description: Definitions and APIs to manages an OpenWiFi network. + version: 2.5.0 + license: + name: BSD3 + url: https://github.com/Telecominfraproject/wlan-cloud-ucentralgw/blob/master/LICENSE + +servers: + - url: 'https://localhost:16005/api/v1' + +security: + - bearerAuth: [] + - ApiKeyAuth: [] + +components: + securitySchemes: + ApiKeyAuth: + type: apiKey + in: header + name: X-API-KEY + bearerAuth: + type: http + scheme: bearer + bearerFormat: JWT + + responses: + NotFound: + $ref: 'https://github.com/Telecominfraproject/wlan-cloud-ucentralsec/blob/main/openpapi/owsec.yaml#/components/responses/NotFound' + Unauthorized: + $ref: 'https://github.com/Telecominfraproject/wlan-cloud-ucentralsec/blob/main/openpapi/owsec.yaml#/components/responses/Unauthorized' + Success: + $ref: 'https://github.com/Telecominfraproject/wlan-cloud-ucentralsec/blob/main/openpapi/owsec.yaml#/components/responses/Success' + BadRequest: + $ref: 'https://github.com/Telecominfraproject/wlan-cloud-ucentralsec/blob/main/openpapi/owsec.yaml#/components/responses/BadRequest' + + schemas: + GLBLRAccountInfo: + type: object + properties: + allOf: + $ref: 'https://github.com/Telecominfraproject/wlan-cloud-owprov/blob/main/openpapi/owprov.yaml#/components/schemas/ObjectInfo' + privateKey: + type: string + country: + type: string + province: + type: string + city: + type: string + organization: + type: string + commonName: + type: string + CSR: + type: string + + GLBLRCertificateInfo: + type: object + properties: + id: + type: string + format: uuid + name: + type: string + accountId: + type: string + format: uuid + csr: + type: string + certificate: + type: string + certificateChain: + type: string + certificateId: + type: string + expiresAt: + type: integer + format: int64 + created: + type: integer + format: int64 + +paths: + /openroaming/globalreach/accounts: + get: + tags: + - OpenRoaming-Global Reach + operationId: getOpenRoaminGlobalReachAccountList + summary: Retrieve account list. + parameters: + - in: query + description: Pagination start (starts at 1. If not specified, 1 is assumed) + name: offset + schema: + type: integer + required: false + - in: query + description: Maximum number of entries to return (if absent, no limit is assumed) + name: limit + schema: + type: integer + required: false + - in: query + description: return the number of accounts + name: countOnly + schema: + type: boolean + required: false + + responses: + 200: + description: The list of accounts + content: + application/json: + schema: + type: array + items: + $ref: '#/components/schemas/GLBLRAccountInfo' + $ref: '#/components/responses/Success' + 400: + $ref: '#/components/responses/BadRequest' + 403: + $ref: '#/components/responses/Unauthorized' + 404: + $ref: '#/components/responses/NotFound' + + /openroaming/globalreach/account/{name}: + get: + tags: + - OpenRoaming-Global Reach + operationId: getOpenRoaminGlobalReachAccount + summary: Retrieve account information. + parameters: + - in: path + description: The account name + name: name + schema: + type: string + required: true + responses: + 200: + $ref: '#/components/schemas/GLBLRAccountInfo' + 400: + $ref: '#/components/responses/BadRequest' + 403: + $ref: '#/components/responses/Unauthorized' + 404: + $ref: '#/components/responses/NotFound' + + delete: + tags: + - OpenRoaming-Global Reach + operationId: deleteOpenRoaminGlobalReachAccount + summary: Delete account information. + parameters: + - in: path + description: The account name + name: name + schema: + type: string + required: true + responses: + 200: + $ref: '#/components/responses/Success' + 400: + $ref: '#/components/responses/BadRequest' + 403: + $ref: '#/components/responses/Unauthorized' + 404: + $ref: '#/components/responses/NotFound' + + post: + tags: + - OpenRoaming-Global Reach + operationId: createOpenRoaminGlobalReachAccount + summary: Create account information. + parameters: + - in: path + description: The account name + name: name + schema: + type: string + required: true + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/GLBLRAccountInfo' + responses: + 200: + $ref: '#/components/schemas/GLBLRAccountInfo' + 400: + $ref: '#/components/responses/BadRequest' + 403: + $ref: '#/components/responses/Unauthorized' + 404: + $ref: '#/components/responses/NotFound' + + put: + tags: + - OpenRoaming-Global Reach + operationId: modifyOpenRoaminGlobalReachAccount + summary: Modify account information. + parameters: + - in: path + description: The account name + name: name + schema: + type: string + required: true + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/GLBLRAccountInfo' + responses: + 200: + $ref: '#/components/schemas/GLBLRAccountInfo' + 400: + $ref: '#/components/responses/BadRequest' + 403: + $ref: '#/components/responses/Unauthorized' + 404: + $ref: '#/components/responses/NotFound' + + /openroaming/globalreach/certificates/{account}: + get: + tags: + - OpenRoaming-Global Reach Certificate + operationId: getOpenRoaminGlobalReachCertificateList + summary: Retrieve certificate list. + parameters: + - in: path + description: The account name + name: account + schema: + type: string + required: true + - in: query + description: Pagination start (starts at 1. If not specified, 1 is assumed) + name: offset + schema: + type: integer + required: false + - in: query + description: Maximum number of entries to return (if absent, no limit is assumed) + name: limit + schema: + type: integer + required: false + - in: query + description: return the number of certificates + name: countOnly + schema: + type: boolean + required: false + + responses: + 200: + description: The list of certificates + content: + application/json: + schema: + type: array + items: + $ref: '#/components/schemas/GLBLRCertificateInfo' + $ref: '#/components/responses/Success' + 400: + $ref: '#/components/responses/BadRequest' + 403: + $ref: '#/components/responses/Unauthorized' + 404: + $ref: '#/components/responses/NotFound' + + /openroaming/globalreach/certificate/{account}/{id}: + get: + tags: + - OpenRoaming-Global Reach Certificate + operationId: getOpenRoaminGlobalReachCertificate + summary: Retrieve certificate information. + parameters: + - in: path + description: The account name + name: account + schema: + type: string + required: true + - in: path + description: The certificate id + name: id + schema: + type: string + required: true + responses: + 200: + $ref: '#/components/schemas/GLBLRCertificateInfo' + 400: + $ref: '#/components/responses/BadRequest' + 403: + $ref: '#/components/responses/Unauthorized' + 404: + $ref: '#/components/responses/NotFound' + + delete: + tags: + - OpenRoaming-Global Reach Certificate + operationId: deleteOpenRoaminGlobalReachCertificate + summary: Delete certificate information. + parameters: + - in: path + description: The account name + name: account + schema: + type: string + required: true + - in: path + description: The certificate id + name: id + schema: + type: string + required: true + responses: + 200: + $ref: '#/components/responses/Success' + 400: + $ref: '#/components/responses/BadRequest' + 403: + $ref: '#/components/responses/Unauthorized' + 404: + $ref: '#/components/responses/NotFound' + + post: + tags: + - OpenRoaming-Global Reach Certificate + operationId: createOpenRoaminGlobalReachCertificate + summary: Create certificate information. + parameters: + - in: path + description: The account name + name: account + schema: + type: string + required: true + - in: path + description: The certificate id + name: id + schema: + type: string + required: true + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/GLBLRCertificateInfo' + responses: + 200: + $ref: '#/components/schemas/GLBLRCertificateInfo' + 400: + $ref: '#/components/responses/BadRequest' + 403: + $ref: '#/components/responses/Unauthorized' + 404: + $ref: '#/components/responses/NotFound' + + put: + tags: + - OpenRoaming-Global Reach Certificate + operationId: modifyOpenRoaminGlobalReachCertificate + summary: Modify certificate information. + parameters: + - in: path + description: The account name + name: account + schema: + type: string + required: true + - in: path + description: The certificate id + name: id + schema: + type: string + required: true + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/GLBLRAccountInfo' + responses: + 200: + $ref: '#/components/schemas/GLBLRAccountInfo' + 400: + $ref: '#/components/responses/BadRequest' + 403: + $ref: '#/components/responses/Unauthorized' + 404: + $ref: '#/components/responses/NotFound' + diff --git a/openapi/ow_or_ameriband.yaml b/openapi/ow_or_ameriband.yaml deleted file mode 100644 index 4193654..0000000 --- a/openapi/ow_or_ameriband.yaml +++ /dev/null @@ -1,268 +0,0 @@ -openapi: 3.0.1 -info: - title: OpenWiFi Open roaming Ameriband Provisioning Model - description: Registration of an OpenRoaming profile with Ameriband for TIP OpenWifi. - version: 1.0.0 - license: - name: BSD3 - url: https://github.com/Telecominfraproject/wlan-cloud-ucentralgw/blob/master/LICENSE - -servers: - - url: 'https://tip.regiatration.ameriband.com:8001/api/v1' - -security: - - bearerAuth: [] - -components: - securitySchemes: - bearerAuth: - type: http - scheme: bearer - - responses: - NotFound: - description: The specified resource was not found. - content: - application/json: - schema: - properties: - ErrorCode: - type: integer - ErrorDetails: - type: string - ErrorDescription: - type: string - - Unauthorized: - description: The requested does not have sufficient rights to perform the operation. - content: - application/json: - schema: - properties: - ErrorCode: - type: integer - enum: - - 0 # Success - - 8 # INVALID_TOKEN - - 9 # EXPIRED_TOKEN - ErrorDetails: - type: string - ErrorDescription: - type: string - - Success: - description: The requested operation was performed. - content: - application/json: - schema: - properties: - Operation: - type: string - Details: - type: string - Code: - type: integer - - BadRequest: - description: The requested operation failed. - content: - application/json: - schema: - properties: - ErrorCode: - type: integer - ErrorDetails: - type: string - ErrorDescription: - type: integer - - schemas: - RegistrationRequest: - type: object - properties: - orgRequestId: - type: string - format: uuid - minLength: 36 - maxLength: 36 - example: - Client will generate a UUID that must be returned in the response. - orgAcceptedTermsAndConditions: - type: boolean - default: false - orgLegalName: - type: string - minLength: 1 - orgWebSite: - type: string - format: url - minLength: 1 - orgContact: - type: string - minLength: 1 - example: - John Smith - orgEmail: - type: string - format: email - minLength: 1 - orgPhone: - type: string - example: - (607)555-1234 or +1(223)555-1222 - orgLocation: - type: string - example: - Boston, NH - LA, CA - orgCertificate: - type: string - minLength: 1 - example: - This must be the entire PEM file content of the certificate, encoded using base64 - - RegistrationResponse: - type: object - properties: - orgRequestId: - type: string - format: uuid - minLength: 36 - maxLength: 36 - example: - This should be the same orgRequestId passed during registration. - orgNASID: - type: string - minLength: 10 - description: - This is the NASID generated by Ameriband. It will be used by the operator as NASID when contacting Ameriband. - ameribandCertificate: - type: string - minLength: 1 - example: - This must be the entire PEM file content of the certificate, encoded using base64 - - RegistrationInformationRequest: - type: object - properties: - link: - description: This should be the link where a potential registrant can read the terms and conditions of registering with Ameriband. - type: string - format: url - minLength: 1 - example: - https://ameriband.com/romain-registration.html - -paths: - /termsAndConditions: - get: - summary: The registrant must be given a chance to view the terms and conditions of the relationship they are entering into - operationId: getTermsAndConditions - responses: - 200: - description: Sucessfully retrieved Terms and Conditions - content: - application/json: - schema: - $ref: '#/components/schemas/RegistrationInformationRequest' - 404: - $ref: '#/components/responses/Unauthorized' - - /registration: - get: - tags: - - Registration - operationId: getRegistrationInformation - summary: This should return the information from a registration based on the NASID - parameters: - - in: query - name: orgNASID - schema: - type: string - required: true - example: - This is the orgNASID returned during registration. - responses: - 200: - $ref: '#/components/schemas/RegistrationResponse' - 403: - $ref: '#/components/responses/Unauthorized' - 404: - $ref: '#/components/responses/NotFound' - - post: - summary: Called when the registrant ahs read the T&Cs and iw willing to submit their information to enter in a partnership - tags: - - Registration - operationId: createRegistration - requestBody: - required: true - content: - application/json: - schema: - $ref: '#/components/schemas/RegistrationRequest' - responses: - 200: - description: Succesfully registered - content: - application/json: - schema: - $ref: '#/components/schemas/RegistrationResponse' - 400: - description: Registration failed due to missing or incomplete information - $ref: '#/components/responses/BadRequest' - 403: - $ref: '#/components/responses/Unauthorized' - - put: - summary: Called when the registrant needs to update its information with Ameriband. The does not generate a new NASID. - tags: - - Registration - operationId: updateRegistration - parameters: - - in: query - name: orgNASID - schema: - type: string - required: true - example: - This is the orgNASID returned during registration. - requestBody: - required: true - content: - application/json: - schema: - $ref: '#/components/schemas/RegistrationRequest' - responses: - 200: - description: Succesfully found the information based on the orgNASID - content: - application/json: - schema: - $ref: '#/components/schemas/RegistrationResponse' - 400: - $ref: '#/components/responses/BadRequest' - 403: - $ref: '#/components/responses/Unauthorized' - 404: - $ref: '#/components/responses/NotFound' - - delete: - tags: - - Registration - summary: When a registrant wants to terminate a relationship with Ameriband. Ameriband should also delete all information from the registrant - operationId: deleteRegistration - parameters: - - in: query - name: orgNASID - schema: - type: string - required: true - example: - This is the orgNASID returned during registration. - responses: - 204: - $ref: '#/components/responses/Success' - 403: - $ref: '#/components/responses/Unauthorized' - 404: - $ref: '#/components/responses/NotFound' diff --git a/src/OpenRoamin_GlobalReach.cpp b/src/OpenRoamin_GlobalReach.cpp index d5fa293..e023014 100644 --- a/src/OpenRoamin_GlobalReach.cpp +++ b/src/OpenRoamin_GlobalReach.cpp @@ -16,7 +16,9 @@ namespace OpenWifi { poco_information(Logger(), "Stopped..."); } - bool OpenRoaming_GlobalReach::GetAccountInfo(const std::string &AccountName, ProvObjects::GLBLRAccountInfo &Account) { + bool OpenRoaming_GlobalReach::GetAccountInfo( + [[maybe_unused]] const std::string &AccountName, + [[maybe_unused]] ProvObjects::GLBLRAccountInfo &Account) { /* Poco::URI URI{"https://config.openro.am/v1/config"}; std::string Path(URI.getPathAndQuery()); @@ -43,7 +45,9 @@ namespace OpenWifi { return true; } - bool OpenRoaming_GlobalReach::CreateRadsecCertificate(const std::string &AccountName, ProvObjects::GLBLRCertificateInfo &NewCertificate) { + bool OpenRoaming_GlobalReach::CreateRadsecCertificate( + [[maybe_unused]] const std::string &AccountName, + [[maybe_unused]] ProvObjects::GLBLRCertificateInfo &NewCertificate) { /* Poco::URI URI{"https://config.openro.am/v1/radsec/issue"}; @@ -77,8 +81,10 @@ namespace OpenWifi { return true; } - bool OpenRoaming_GlobalReach::GetRadsecCertificate(const std::string &AccountName, std::string &CertificateId, - ProvObjects::GLBLRCertificateInfo &NewCertificate) { + bool OpenRoaming_GlobalReach::GetRadsecCertificate( + [[maybe_unused]] const std::string &AccountName, + [[maybe_unused]] std::string &CertificateId, + [[maybe_unused]] ProvObjects::GLBLRCertificateInfo &NewCertificate) { return true; } diff --git a/src/RESTAPI/RESTAPI_openroaming_gr_acct_handler.cpp b/src/RESTAPI/RESTAPI_openroaming_gr_acct_handler.cpp new file mode 100644 index 0000000..481e6c0 --- /dev/null +++ b/src/RESTAPI/RESTAPI_openroaming_gr_acct_handler.cpp @@ -0,0 +1,120 @@ +// +// Created by stephane bourque on 2023-09-11. +// + +#include "RESTAPI_openroaming_gr_acct_handler.h" + +namespace OpenWifi { + + void RESTAPI_openroaming_gr_acct_handler::DoGet() { + auto Account = GetBinding("account",""); + if(Account.empty()) { + return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters); + } + + ProvObjects::GLBLRAccountInfo Record; + if(DB_.GetRecord("id",Account,Record)) { + return ReturnObject(Record); + } + return NotFound(); + } + + void RESTAPI_openroaming_gr_acct_handler::DoDelete() { + auto Account = GetBinding("account",""); + if(Account.empty()) { + return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters); + } + + ProvObjects::GLBLRAccountInfo Record; + if(!DB_.GetRecord("id",Account,Record)) { + return NotFound(); + } + + StorageService()->GLBLRCertsDB().DeleteRecords(fmt::format(" accountId='{}' ", Account)); + DB_.DeleteRecord("id", Account); + + return OK(); + } + + void RESTAPI_openroaming_gr_acct_handler::DoPost() { + auto Account = GetBinding("account",""); + if(Account.empty()) { + return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters); + } + + const auto &RawObject = ParsedBody_; + ProvObjects::GLBLRAccountInfo NewObject; + if( !NewObject.from_json(RawObject)) { + return BadRequest(OpenWifi::RESTAPI::Errors::InvalidJSONDocument); + } + + if(RawObject->has("privateKey")) { + if(!NewObject.privateKey.empty() && !Utils::VerifyECKey(NewObject.privateKey)) { + return BadRequest(RESTAPI::Errors::NotAValidECKey); + } + } + + if( NewObject.commonName.empty() || NewObject.organization.empty() || + NewObject.city.empty() || NewObject.province.empty() || NewObject.country.empty() ) { + return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters); + } + + NewObject.CSR = Utils::CreateX509CSR(NewObject.country,NewObject.province, NewObject.city, NewObject.organization, NewObject.commonName); + + ProvObjects::CreateObjectInfo(RawObject,UserInfo_.userinfo,NewObject.info); + + if(DB_.CreateRecord(NewObject)) { + ProvObjects::GLBLRAccountInfo StoredObject; + DB_.GetRecord("id",NewObject.info.id,StoredObject); + return ReturnObject(StoredObject); + } + + return BadRequest(RESTAPI::Errors::RecordNotCreated); + } + + void RESTAPI_openroaming_gr_acct_handler::DoPut() { + auto Account = GetBinding("account",""); + if(Account.empty()) { + return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters); + } + + const auto &RawObject = ParsedBody_; + ProvObjects::GLBLRAccountInfo Modify; + if(!Modify.from_json(RawObject)) { + return BadRequest(OpenWifi::RESTAPI::Errors::InvalidJSONDocument); + } + + ProvObjects::GLBLRAccountInfo Existing; + if(!DB_.GetRecord("id",Account,Existing)) { + return NotFound(); + } + + if(!ProvObjects::UpdateObjectInfo(RawObject,UserInfo_.userinfo,Existing.info)) { + return BadRequest(OpenWifi::RESTAPI::Errors::InvalidJSONDocument); + } + + if(RawObject->has("privateKey")) { + if(!Modify.privateKey.empty() && !Utils::VerifyECKey(Modify.privateKey)) { + return BadRequest(RESTAPI::Errors::NotAValidECKey); + } + Existing.privateKey = Modify.privateKey; + } + + auto Modified = AssignIfPresent(RawObject,"country",Existing.country) || + AssignIfPresent(RawObject,"commonName",Existing.commonName) || + AssignIfPresent(RawObject,"city",Existing.city) || + AssignIfPresent(RawObject,"province",Existing.province) || + AssignIfPresent(RawObject,"organization",Existing.organization); + if(Modified) { + Existing.CSR = Utils::CreateX509CSR(Existing.country,Existing.province, Existing.city, Existing.organization, Existing.commonName); + } + + if(DB_.UpdateRecord("id",Existing.info.id,Existing)) { + ProvObjects::GLBLRAccountInfo StoredObject; + DB_.GetRecord("id",Existing.info.id,StoredObject); + return ReturnObject(StoredObject); + } + return BadRequest(RESTAPI::Errors::RecordNotUpdated); + } + +} // OpenWifi \ No newline at end of file diff --git a/src/RESTAPI/RESTAPI_openroaming_gr_acct_handler.h b/src/RESTAPI/RESTAPI_openroaming_gr_acct_handler.h new file mode 100644 index 0000000..fcf5298 --- /dev/null +++ b/src/RESTAPI/RESTAPI_openroaming_gr_acct_handler.h @@ -0,0 +1,31 @@ +// +// Created by stephane bourque on 2023-09-11. +// + +#pragma once +#include "StorageService.h" +#include "framework/RESTAPI_Handler.h" + +namespace OpenWifi { + class RESTAPI_openroaming_gr_acct_handler : public RESTAPIHandler { + public: + RESTAPI_openroaming_gr_acct_handler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, + RESTAPI_GenericServerAccounting &Server, uint64_t TransactionId, + bool Internal) + : RESTAPIHandler(bindings, L, + std::vector{Poco::Net::HTTPRequest::HTTP_GET, + Poco::Net::HTTPRequest::HTTP_DELETE, + Poco::Net::HTTPRequest::HTTP_PUT, + Poco::Net::HTTPRequest::HTTP_POST, + Poco::Net::HTTPRequest::HTTP_OPTIONS}, + Server, TransactionId, Internal) {} + static auto PathName() { return std::list{"/api/v1/openroaming/globalreach/account/{id}"}; }; + + private: + GLBLRAccountInfoDB &DB_ = StorageService()->GLBLRAccountInfoDB(); + void DoGet() final; + void DoPost() final; + void DoPut() final; + void DoDelete() final; + }; +} // namespace OpenWifi diff --git a/src/RESTAPI/RESTAPI_openroaming_gr_cert_handler.cpp b/src/RESTAPI/RESTAPI_openroaming_gr_cert_handler.cpp new file mode 100644 index 0000000..e7aa4e1 --- /dev/null +++ b/src/RESTAPI/RESTAPI_openroaming_gr_cert_handler.cpp @@ -0,0 +1,25 @@ +// +// Created by stephane bourque on 2023-09-11. +// + +#include "RESTAPI_openroaming_gr_cert_handler.h" + +namespace OpenWifi { + + void RESTAPI_openroaming_gr_cert_handler::DoGet() { + return BadRequest(RESTAPI::Errors::NotImplemented); + } + + void RESTAPI_openroaming_gr_cert_handler::DoDelete() { + return BadRequest(RESTAPI::Errors::NotImplemented); + } + + void RESTAPI_openroaming_gr_cert_handler::DoPost() { + return BadRequest(RESTAPI::Errors::NotImplemented); + } + + void RESTAPI_openroaming_gr_cert_handler::DoPut() { + return BadRequest(RESTAPI::Errors::NotImplemented); + } + +} // OpenWifi \ No newline at end of file diff --git a/src/RESTAPI/RESTAPI_openroaming_gr_cert_handler.h b/src/RESTAPI/RESTAPI_openroaming_gr_cert_handler.h new file mode 100644 index 0000000..c79ad62 --- /dev/null +++ b/src/RESTAPI/RESTAPI_openroaming_gr_cert_handler.h @@ -0,0 +1,31 @@ +// +// Created by stephane bourque on 2023-09-11. +// + +#pragma once +#include "StorageService.h" +#include "framework/RESTAPI_Handler.h" + +namespace OpenWifi { + class RESTAPI_openroaming_gr_cert_handler : public RESTAPIHandler { + public: + RESTAPI_openroaming_gr_cert_handler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, + RESTAPI_GenericServerAccounting &Server, uint64_t TransactionId, + bool Internal) + : RESTAPIHandler(bindings, L, + std::vector{Poco::Net::HTTPRequest::HTTP_GET, + Poco::Net::HTTPRequest::HTTP_DELETE, + Poco::Net::HTTPRequest::HTTP_PUT, + Poco::Net::HTTPRequest::HTTP_POST, + Poco::Net::HTTPRequest::HTTP_OPTIONS}, + Server, TransactionId, Internal) {} + static auto PathName() { return std::list{"/api/v1/openroaming/globalreach/certificate/{account}/{id}"}; }; + + private: + GLBLRCertsDB &DB_ = StorageService()->GLBLRCertsDB(); + void DoGet() final; + void DoPost() final; + void DoPut() final; + void DoDelete() final; + }; +} // namespace OpenWifi diff --git a/src/RESTAPI/RESTAPI_openroaming_gr_list_acct_handler.cpp b/src/RESTAPI/RESTAPI_openroaming_gr_list_acct_handler.cpp new file mode 100644 index 0000000..8b97884 --- /dev/null +++ b/src/RESTAPI/RESTAPI_openroaming_gr_list_acct_handler.cpp @@ -0,0 +1,20 @@ +// +// Created by stephane bourque on 2023-09-11. +// + +#include "RESTAPI_openroaming_gr_list_acct_handler.h" + +namespace OpenWifi { + + void RESTAPI_openroaming_gr_list_acct_handler::DoGet() { + + if(GetBoolParameter("countOnly")) { + return ReturnCountOnly(DB_.Count()); + } + + std::vector Accounts; + DB_.GetRecords(QB_.Offset,QB_.Limit,Accounts); + return ReturnObject(Accounts); + } + +} // OpenWifi \ No newline at end of file diff --git a/src/RESTAPI/RESTAPI_openroaming_gr_list_acct_handler.h b/src/RESTAPI/RESTAPI_openroaming_gr_list_acct_handler.h new file mode 100644 index 0000000..8d37f94 --- /dev/null +++ b/src/RESTAPI/RESTAPI_openroaming_gr_list_acct_handler.h @@ -0,0 +1,29 @@ +// +// Created by stephane bourque on 2023-09-11. +// + + +#pragma once +#include "StorageService.h" +#include "framework/RESTAPI_Handler.h" + +namespace OpenWifi { + class RESTAPI_openroaming_gr_list_acct_handler : public RESTAPIHandler { + public: + RESTAPI_openroaming_gr_list_acct_handler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, + RESTAPI_GenericServerAccounting &Server, uint64_t TransactionId, + bool Internal) + : RESTAPIHandler(bindings, L, + std::vector{Poco::Net::HTTPRequest::HTTP_GET, + Poco::Net::HTTPRequest::HTTP_OPTIONS}, + Server, TransactionId, Internal) {} + static auto PathName() { return std::list{"/api/v1/openroaming/globalreach/accounts"}; }; + + private: + GLBLRAccountInfoDB &DB_ = StorageService()->GLBLRAccountInfoDB(); + void DoGet() final; + void DoPost() final{}; + void DoPut() final{}; + void DoDelete() final{}; + }; +} // namespace OpenWifi diff --git a/src/RESTAPI/RESTAPI_openroaming_gr_list_certificates.cpp b/src/RESTAPI/RESTAPI_openroaming_gr_list_certificates.cpp new file mode 100644 index 0000000..1f102fe --- /dev/null +++ b/src/RESTAPI/RESTAPI_openroaming_gr_list_certificates.cpp @@ -0,0 +1,27 @@ +// +// Created by stephane bourque on 2023-09-11. +// + +#include "RESTAPI_openroaming_gr_list_certificates.h" + +namespace OpenWifi { + + void RESTAPI_openroaming_gr_list_certificates::DoGet() { + + auto Account = GetParameter("account",""); + if(Account.empty()) { + return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters); + } + + auto Where = fmt::format(" accountId='{}'", Account); + + if(GetBoolParameter("countOnly")) { + return ReturnCountOnly(DB_.Count(Where)); + } + + std::vector Certificates; + DB_.GetRecords(QB_.Offset,QB_.Limit,Certificates, Where); + return ReturnObject(Certificates); + } + +} // OpenWifi \ No newline at end of file diff --git a/src/RESTAPI/RESTAPI_openroaming_gr_list_certificates.h b/src/RESTAPI/RESTAPI_openroaming_gr_list_certificates.h new file mode 100644 index 0000000..1485239 --- /dev/null +++ b/src/RESTAPI/RESTAPI_openroaming_gr_list_certificates.h @@ -0,0 +1,29 @@ +// +// Created by stephane bourque on 2023-09-11. +// + +#pragma once +#include "StorageService.h" +#include "framework/RESTAPI_Handler.h" + +namespace OpenWifi { + class RESTAPI_openroaming_gr_list_certificates : public RESTAPIHandler { + public: + RESTAPI_openroaming_gr_list_certificates(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, + RESTAPI_GenericServerAccounting &Server, uint64_t TransactionId, + bool Internal) + : RESTAPIHandler(bindings, L, + std::vector{Poco::Net::HTTPRequest::HTTP_GET, + Poco::Net::HTTPRequest::HTTP_OPTIONS}, + Server, TransactionId, Internal) {} + static auto PathName() { return std::list{"/api/v1/openroaming/globalreach/certificates/{account}"}; }; + + private: + GLBLRCertsDB &DB_ = StorageService()->GLBLRCertsDB(); + void DoGet() final; + void DoPost() final{}; + void DoPut() final{}; + void DoDelete() final{}; + }; +} // namespace OpenWifi + diff --git a/src/RESTAPI/RESTAPI_routers.cpp b/src/RESTAPI/RESTAPI_routers.cpp index 1bf95e1..441f2aa 100644 --- a/src/RESTAPI/RESTAPI_routers.cpp +++ b/src/RESTAPI/RESTAPI_routers.cpp @@ -35,6 +35,10 @@ #include "RESTAPI/RESTAPI_variables_list_handler.h" #include "RESTAPI/RESTAPI_venue_handler.h" #include "RESTAPI/RESTAPI_venue_list_handler.h" +#include "RESTAPI/RESTAPI_openroaming_gr_acct_handler.h" +#include "RESTAPI/RESTAPI_openroaming_gr_list_acct_handler.h" +#include "RESTAPI/RESTAPI_openroaming_gr_cert_handler.h" +#include "RESTAPI/RESTAPI_openroaming_gr_list_certificates.h" #include "framework/RESTAPI_SystemCommand.h" #include "framework/RESTAPI_WebSocketServer.h" @@ -60,7 +64,9 @@ namespace OpenWifi { RESTAPI_operators_list_handler, RESTAPI_service_class_handler, RESTAPI_service_class_list_handler, RESTAPI_op_contact_handler, RESTAPI_op_contact_list_handler, RESTAPI_op_location_handler, - RESTAPI_op_location_list_handler, RESTAPI_asset_server, RESTAPI_overrides_handler>( + RESTAPI_op_location_list_handler, RESTAPI_asset_server, RESTAPI_overrides_handler, + RESTAPI_openroaming_gr_acct_handler, RESTAPI_openroaming_gr_list_acct_handler, + RESTAPI_openroaming_gr_cert_handler, RESTAPI_openroaming_gr_list_certificates>( Path, Bindings, L, S, TransactionId); } @@ -82,7 +88,9 @@ namespace OpenWifi { RESTAPI_operators_list_handler, RESTAPI_service_class_handler, RESTAPI_service_class_list_handler, RESTAPI_op_contact_handler, RESTAPI_op_contact_list_handler, RESTAPI_op_location_handler, - RESTAPI_op_location_list_handler, RESTAPI_overrides_handler>(Path, Bindings, L, S, + RESTAPI_op_location_list_handler, RESTAPI_overrides_handler, + RESTAPI_openroaming_gr_acct_handler, RESTAPI_openroaming_gr_list_acct_handler, + RESTAPI_openroaming_gr_cert_handler, RESTAPI_openroaming_gr_list_certificates>(Path, Bindings, L, S, TransactionId); } } // namespace OpenWifi \ No newline at end of file diff --git a/src/RESTObjects/RESTAPI_ProvObjects.cpp b/src/RESTObjects/RESTAPI_ProvObjects.cpp index bafd9ac..05de8f9 100644 --- a/src/RESTObjects/RESTAPI_ProvObjects.cpp +++ b/src/RESTObjects/RESTAPI_ProvObjects.cpp @@ -1202,6 +1202,7 @@ namespace OpenWifi::ProvObjects { field_to_json(Obj, "city", city); field_to_json(Obj, "organization", organization); field_to_json(Obj, "commonName", commonName); + field_to_json(Obj, "CSR", CSR); } bool GLBLRAccountInfo::from_json(const Poco::JSON::Object::Ptr &Obj) { @@ -1213,6 +1214,7 @@ namespace OpenWifi::ProvObjects { field_from_json(Obj, "city", city); field_from_json(Obj, "organization", organization); field_from_json(Obj, "commonName", commonName); + field_from_json(Obj, "CSR", CSR); return true; } catch (const Poco::Exception &E) { diff --git a/src/RESTObjects/RESTAPI_ProvObjects.h b/src/RESTObjects/RESTAPI_ProvObjects.h index ffdc136..7116b8b 100644 --- a/src/RESTObjects/RESTAPI_ProvObjects.h +++ b/src/RESTObjects/RESTAPI_ProvObjects.h @@ -751,6 +751,7 @@ namespace OpenWifi::ProvObjects { ObjectInfo info; std::string privateKey; std::string country, province, city, organization, commonName; + std::string CSR; void to_json(Poco::JSON::Object &Obj) const; bool from_json(const Poco::JSON::Object::Ptr &Obj); diff --git a/src/framework/RESTAPI_Handler.h b/src/framework/RESTAPI_Handler.h index b74d6e7..d6f31be 100644 --- a/src/framework/RESTAPI_Handler.h +++ b/src/framework/RESTAPI_Handler.h @@ -584,7 +584,27 @@ namespace OpenWifi { return ReturnRawJSON(os.str()); } - inline void ReturnRawJSON(const std::string &json_doc) { + template void ReturnObject(const std::vector &Objects) { + Poco::JSON::Array Arr; + for(const auto &Object:Objects) { + Poco::JSON::Object O; + Object.to_json(O); + Arr.add(O); + } + std::ostringstream os; + Arr.stringify(os); + return ReturnRawJSON(os.str()); + } + + template void ReturnObject(const T &Object) { + Poco::JSON::Object O; + Object.to_json(O); + std::ostringstream os; + O.stringify(os); + return ReturnRawJSON(os.str()); + } + + inline void ReturnRawJSON(const std::string &json_doc) { PrepareResponse(); if (Request != nullptr) { // can we compress ??? diff --git a/src/framework/ow_constants.h b/src/framework/ow_constants.h index 2d45a3d..b71f247 100644 --- a/src/framework/ow_constants.h +++ b/src/framework/ow_constants.h @@ -407,6 +407,7 @@ namespace OpenWifi::RESTAPI::Errors { }; static const struct msg DefFirmwareNameExists { 1172, "Firmware name already exists." }; + static const struct msg NotAValidECKey { 1173, "Provided key supplied is not valid." }; static const struct msg SimulationDoesNotExist { 7000, "Simulation Instance ID does not exist." diff --git a/src/framework/utils.cpp b/src/framework/utils.cpp index c37ff64..ad65bcf 100644 --- a/src/framework/utils.cpp +++ b/src/framework/utils.cpp @@ -4,7 +4,7 @@ #include "Poco/Path.h" #include "Poco/TemporaryFile.h" - +#include "Poco/Crypto/ECKey.h" #include "framework/AppServiceRegistry.h" #include "framework/utils.h" @@ -609,7 +609,7 @@ namespace OpenWifi::Utils { return DT.timestamp().epochTime(); } - bool CreateX509CSR(const std::string &Country, const std::string &Province, const std::string &City, + std::string CreateX509CSR(const std::string &Country, const std::string &Province, const std::string &City, const std::string &Organization, const std::string &CommonName, int bits ) { int ret = 0; RSA *r = nullptr; @@ -632,8 +632,11 @@ namespace OpenWifi::Utils { const char *szCommon = CommonName.c_str(); Poco::TemporaryFile CsrPath; + std::string Result; + std::ifstream ifs; + std::ostringstream ss; -// 1. generate rsa key + // 1. generate rsa key bne = BN_new(); ret = BN_set_word(bne,e); if(ret != 1){ @@ -700,6 +703,10 @@ namespace OpenWifi::Utils { out = BIO_new_file(CsrPath.path().c_str(),"w"); ret = PEM_write_bio_X509_REQ(out, x509_req); + ifs.open(CsrPath.path().c_str(),std::ios_base::binary|std::ios_base::in); + Poco::StreamCopier::copyStream(ifs,ss); + ifs.close(); + Result = ss.str(); // 6. free free_all: X509_REQ_free(x509_req); @@ -708,8 +715,25 @@ namespace OpenWifi::Utils { EVP_PKEY_free(pKey); BN_free(bne); - return (ret == 1); + return Result; + } + + bool VerifyECKey(const std::string &key) { + try { + Poco::TemporaryFile F; + + std::ofstream of(F.path().c_str(), std::ios_base::trunc | std::ios_base::out | std::ios_base::binary); + of << key; + of.close(); + auto Key = Poco::SharedPtr( + new Poco::Crypto::ECKey("", F.path(),"")); + + return true; + } catch (const Poco::Exception &E) { + + } + return false; } } // namespace OpenWifi::Utils diff --git a/src/framework/utils.h b/src/framework/utils.h index 89ba52a..2580b78 100644 --- a/src/framework/utils.h +++ b/src/framework/utils.h @@ -247,6 +247,7 @@ namespace OpenWifi::Utils { return count; } - bool CreateX509CSR(const std::string &Country, const std::string &Province, const std::string &City, + std::string CreateX509CSR(const std::string &Country, const std::string &Province, const std::string &City, const std::string &Organization, const std::string &CommonName, int bits=2048); + bool VerifyECKey(const std::string &key); } // namespace OpenWifi::Utils diff --git a/src/storage/storage_glblraccounts.cpp b/src/storage/storage_glblraccounts.cpp index 7f616c3..ab0441f 100644 --- a/src/storage/storage_glblraccounts.cpp +++ b/src/storage/storage_glblraccounts.cpp @@ -11,7 +11,7 @@ namespace OpenWifi { - static ORM::FieldVec GLBLRAccountInfoDB_Fields{// object info + static ORM::FieldVec GLBLRAccountInfoDB_Fields{ ORM::Field{"id", 64, true}, ORM::Field{"name", ORM::FieldType::FT_TEXT}, ORM::Field{"description", ORM::FieldType::FT_TEXT}, @@ -23,7 +23,8 @@ namespace OpenWifi { ORM::Field{"province", ORM::FieldType::FT_TEXT}, ORM::Field{"city", ORM::FieldType::FT_TEXT}, ORM::Field{"organization", ORM::FieldType::FT_TEXT}, - ORM::Field{"commonName", ORM::FieldType::FT_TEXT} + ORM::Field{"commonName", ORM::FieldType::FT_TEXT}, + ORM::Field{"CSR", ORM::FieldType::FT_TEXT} }; static ORM::IndexVec GLBLRAccountInfoDB_Indexes{ @@ -65,6 +66,7 @@ void ORM::DB(); Out.organization = In.get<10>(); Out.commonName = In.get<11>(); + Out.CSR = In.get<12>(); } template <> @@ -82,4 +84,5 @@ void ORM::DB(In.city); Out.set<10>(In.organization); Out.set<11>(In.commonName); + Out.set<12>(In.CSR); } diff --git a/src/storage/storage_glblraccounts.h b/src/storage/storage_glblraccounts.h index bc213c1..577769a 100644 --- a/src/storage/storage_glblraccounts.h +++ b/src/storage/storage_glblraccounts.h @@ -17,6 +17,7 @@ namespace OpenWifi { std::string, std::string, std::string, + std::string, std::string> GLBLRAccountsDBRecordType; From 882603193941ac24bc14ade5cfbb4411ba0a6193 Mon Sep 17 00:00:00 2001 From: stephb9959 Date: Tue, 12 Sep 2023 07:45:44 -0700 Subject: [PATCH 04/46] https://telecominfraproject.atlassian.net/browse/WIFI-7831 Signed-off-by: stephb9959 --- openapi/openroaming_globalreach.yaml | 2 ++ src/RESTObjects/RESTAPI_ProvObjects.cpp | 2 ++ src/RESTObjects/RESTAPI_ProvObjects.h | 1 + src/storage/storage_glblraccounts.cpp | 5 ++++- src/storage/storage_glblraccounts.h | 1 + 5 files changed, 10 insertions(+), 1 deletion(-) diff --git a/openapi/openroaming_globalreach.yaml b/openapi/openroaming_globalreach.yaml index 9e9b5ff..56c7b42 100644 --- a/openapi/openroaming_globalreach.yaml +++ b/openapi/openroaming_globalreach.yaml @@ -55,6 +55,8 @@ components: type: string CSR: type: string + GlobalReachAcctId: + type: string GLBLRCertificateInfo: type: object diff --git a/src/RESTObjects/RESTAPI_ProvObjects.cpp b/src/RESTObjects/RESTAPI_ProvObjects.cpp index 05de8f9..6254e4a 100644 --- a/src/RESTObjects/RESTAPI_ProvObjects.cpp +++ b/src/RESTObjects/RESTAPI_ProvObjects.cpp @@ -1203,6 +1203,7 @@ namespace OpenWifi::ProvObjects { field_to_json(Obj, "organization", organization); field_to_json(Obj, "commonName", commonName); field_to_json(Obj, "CSR", CSR); + field_to_json(Obj, "GlobalReachAcctId", GlobalReachAcctId); } bool GLBLRAccountInfo::from_json(const Poco::JSON::Object::Ptr &Obj) { @@ -1215,6 +1216,7 @@ namespace OpenWifi::ProvObjects { field_from_json(Obj, "organization", organization); field_from_json(Obj, "commonName", commonName); field_from_json(Obj, "CSR", CSR); + field_from_json(Obj, "GlobalReachAcctId", GlobalReachAcctId); return true; } catch (const Poco::Exception &E) { diff --git a/src/RESTObjects/RESTAPI_ProvObjects.h b/src/RESTObjects/RESTAPI_ProvObjects.h index 7116b8b..1ef7b27 100644 --- a/src/RESTObjects/RESTAPI_ProvObjects.h +++ b/src/RESTObjects/RESTAPI_ProvObjects.h @@ -752,6 +752,7 @@ namespace OpenWifi::ProvObjects { std::string privateKey; std::string country, province, city, organization, commonName; std::string CSR; + std::string GlobalReachAcctId; void to_json(Poco::JSON::Object &Obj) const; bool from_json(const Poco::JSON::Object::Ptr &Obj); diff --git a/src/storage/storage_glblraccounts.cpp b/src/storage/storage_glblraccounts.cpp index ab0441f..37210b0 100644 --- a/src/storage/storage_glblraccounts.cpp +++ b/src/storage/storage_glblraccounts.cpp @@ -24,7 +24,8 @@ namespace OpenWifi { ORM::Field{"city", ORM::FieldType::FT_TEXT}, ORM::Field{"organization", ORM::FieldType::FT_TEXT}, ORM::Field{"commonName", ORM::FieldType::FT_TEXT}, - ORM::Field{"CSR", ORM::FieldType::FT_TEXT} + ORM::Field{"CSR", ORM::FieldType::FT_TEXT}, + ORM::Field{"GlobalReachAcctId", ORM::FieldType::FT_TEXT} }; static ORM::IndexVec GLBLRAccountInfoDB_Indexes{ @@ -67,6 +68,7 @@ void ORM::DB(); Out.commonName = In.get<11>(); Out.CSR = In.get<12>(); + Out.GlobalReachAcctId = In.get<13>(); } template <> @@ -85,4 +87,5 @@ void ORM::DB(In.organization); Out.set<11>(In.commonName); Out.set<12>(In.CSR); + Out.set<13>(In.GlobalReachAcctId); } diff --git a/src/storage/storage_glblraccounts.h b/src/storage/storage_glblraccounts.h index 577769a..dc0f8d3 100644 --- a/src/storage/storage_glblraccounts.h +++ b/src/storage/storage_glblraccounts.h @@ -18,6 +18,7 @@ namespace OpenWifi { std::string, std::string, std::string, + std::string, std::string> GLBLRAccountsDBRecordType; From ca7c618c16bce47547074135e52f8c07c294bd90 Mon Sep 17 00:00:00 2001 From: stephb9959 Date: Tue, 12 Sep 2023 09:00:59 -0700 Subject: [PATCH 05/46] https://telecominfraproject.atlassian.net/browse/WIFI-7831 Signed-off-by: stephb9959 --- src/OpenRoamin_GlobalReach.cpp | 67 +++++++++++++++++++ src/OpenRoamin_GlobalReach.h | 5 +- .../RESTAPI_openroaming_gr_acct_handler.cpp | 21 ++++-- src/framework/ow_constants.h | 1 + 4 files changed, 89 insertions(+), 5 deletions(-) diff --git a/src/OpenRoamin_GlobalReach.cpp b/src/OpenRoamin_GlobalReach.cpp index e023014..d98aaa7 100644 --- a/src/OpenRoamin_GlobalReach.cpp +++ b/src/OpenRoamin_GlobalReach.cpp @@ -3,6 +3,15 @@ // #include "OpenRoamin_GlobalReach.h" +#include +#include +#include +#include +#include +#include +#include + +#include namespace OpenWifi { @@ -88,4 +97,62 @@ namespace OpenWifi { return true; } + std::string OpenRoaming_GlobalReach::MakeToken(const std::string &GlobalReachAccountId, const std::string &PrivateKey) { + Poco::JWT::Token token; + + token.setType("JWT"); + token.setAlgorithm("ES256"); + token.setIssuedAt(std::time(nullptr)); + + token.payload().set("iss", GlobalReachAccountId); + token.payload().set("iat", (unsigned long) std::time(nullptr)); + + Poco::SharedPtr Key; + auto KeyHash = Utils::ComputeHash(PrivateKey); + auto KeyHint = PrivateKeys_.find(KeyHash); + if(KeyHint!=PrivateKeys_.end()) { + Key = KeyHint->second; + } else { + Poco::TemporaryFile F; + std::ofstream ofs(F.path().c_str(),std::ios_base::trunc|std::ios_base::out|std::ios_base::binary); + ofs << PrivateKey; + ofs.close(); + auto NewKey = Poco::SharedPtr( + new Poco::Crypto::ECKey("", F.path(),"")); + Key = PrivateKeys_[KeyHash] = NewKey; + } + + Poco::JWT::Signer Signer; + Signer.setECKey(Key); + Signer.addAllAlgorithms(); + return Signer.sign(token, Poco::JWT::Signer::ALGO_ES256); + } + + bool OpenRoaming_GlobalReach::VerifyAccount(const std::string &GlobalReachAccountId, const std::string &PrivateKey, [[ + maybe_unused]] std::string &Name) { + auto BearerToken = MakeToken(GlobalReachAccountId, PrivateKey); + + Poco::URI URI{"https://config.openro.am/v1/config"}; + std::string Path(URI.getPathAndQuery()); + Poco::Net::HTTPRequest Request(Poco::Net::HTTPRequest::HTTP_GET, Path, + Poco::Net::HTTPMessage::HTTP_1_1); + Request.add("Authorization", "Bearer " + BearerToken); + + Poco::Net::HTTPSClientSession Session(URI.getHost(), URI.getPort()); + Session.setTimeout(Poco::Timespan(10000, 10000)); + Session.sendRequest(Request); + Poco::Net::HTTPResponse Response; + std::istream &is = Session.receiveResponse(Response); + if(Response.getStatus()==Poco::Net::HTTPResponse::HTTP_OK) { + Poco::JSON::Parser P; + auto Result = P.parse(is).extract(); + if(Result->has("name")) { + Name = Result->get("name").toString(); + } + return true; + } + return false; + } + + } // OpenWifi \ No newline at end of file diff --git a/src/OpenRoamin_GlobalReach.h b/src/OpenRoamin_GlobalReach.h index 767329c..3cfea01 100644 --- a/src/OpenRoamin_GlobalReach.h +++ b/src/OpenRoamin_GlobalReach.h @@ -22,9 +22,12 @@ namespace OpenWifi { bool GetAccountInfo(const std::string &AccountName, ProvObjects::GLBLRAccountInfo &Account); bool CreateRadsecCertificate(const std::string &AccountName, ProvObjects::GLBLRCertificateInfo &NewCertificate); bool GetRadsecCertificate(const std::string &AccountName, std::string & CertificateId, ProvObjects::GLBLRCertificateInfo &NewCertificate); + bool VerifyAccount(const std::string &GlobalReachAccountId, const std::string &PrivateKey, std::string &Name); private: - std::string CreateJWTToken(const std::string &AccountName); + std::string MakeToken(const std::string &GlobalReachAccountId, const std::string &PrivateKey); + + std::map> PrivateKeys_; OpenRoaming_GlobalReach() noexcept : SubSystemServer("OpenRoaming_GlobalReach", "GLBL-REACH", "globalreach") { diff --git a/src/RESTAPI/RESTAPI_openroaming_gr_acct_handler.cpp b/src/RESTAPI/RESTAPI_openroaming_gr_acct_handler.cpp index 481e6c0..ab64484 100644 --- a/src/RESTAPI/RESTAPI_openroaming_gr_acct_handler.cpp +++ b/src/RESTAPI/RESTAPI_openroaming_gr_acct_handler.cpp @@ -3,6 +3,7 @@ // #include "RESTAPI_openroaming_gr_acct_handler.h" +#include "OpenRoamin_GlobalReach.h" namespace OpenWifi { @@ -48,10 +49,17 @@ namespace OpenWifi { return BadRequest(OpenWifi::RESTAPI::Errors::InvalidJSONDocument); } - if(RawObject->has("privateKey")) { - if(!NewObject.privateKey.empty() && !Utils::VerifyECKey(NewObject.privateKey)) { - return BadRequest(RESTAPI::Errors::NotAValidECKey); - } + if(NewObject.privateKey.empty() || NewObject.GlobalReachAcctId.empty()) { + return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters); + } + + if(!NewObject.privateKey.empty() && !Utils::VerifyECKey(NewObject.privateKey)) { + return BadRequest(RESTAPI::Errors::NotAValidECKey); + } + + std::string GlobalReachName; + if(!OpenRoaming_GlobalReach()->VerifyAccount(NewObject.GlobalReachAcctId,NewObject.privateKey,GlobalReachName)) { + return BadRequest(RESTAPI::Errors::InvalidGlobalReachAccount); } if( NewObject.commonName.empty() || NewObject.organization.empty() || @@ -100,6 +108,11 @@ namespace OpenWifi { Existing.privateKey = Modify.privateKey; } + std::string GlobalReachName; + if(!OpenRoaming_GlobalReach()->VerifyAccount(Existing.GlobalReachAcctId,Existing.privateKey,GlobalReachName)) { + return BadRequest(RESTAPI::Errors::InvalidGlobalReachAccount); + } + auto Modified = AssignIfPresent(RawObject,"country",Existing.country) || AssignIfPresent(RawObject,"commonName",Existing.commonName) || AssignIfPresent(RawObject,"city",Existing.city) || diff --git a/src/framework/ow_constants.h b/src/framework/ow_constants.h index b71f247..95da446 100644 --- a/src/framework/ow_constants.h +++ b/src/framework/ow_constants.h @@ -408,6 +408,7 @@ namespace OpenWifi::RESTAPI::Errors { static const struct msg DefFirmwareNameExists { 1172, "Firmware name already exists." }; static const struct msg NotAValidECKey { 1173, "Provided key supplied is not valid." }; + static const struct msg InvalidGlobalReachAccount { 1174, "Invalid Global Reach account information (id or key)." }; static const struct msg SimulationDoesNotExist { 7000, "Simulation Instance ID does not exist." From 69dce68d1aa5e24e7f2dbd902d4757d9610e11c0 Mon Sep 17 00:00:00 2001 From: stephb9959 Date: Tue, 12 Sep 2023 10:54:35 -0700 Subject: [PATCH 06/46] https://telecominfraproject.atlassian.net/browse/WIFI-7831 Signed-off-by: stephb9959 --- openapi/openroaming_globalreach.yaml | 63 ++--- src/OpenRoamin_GlobalReach.cpp | 227 +++++++++++------- src/OpenRoamin_GlobalReach.h | 13 +- .../RESTAPI_openroaming_gr_cert_handler.cpp | 67 +++++- .../RESTAPI_openroaming_gr_cert_handler.h | 3 +- 5 files changed, 219 insertions(+), 154 deletions(-) diff --git a/openapi/openroaming_globalreach.yaml b/openapi/openroaming_globalreach.yaml index 56c7b42..c71e471 100644 --- a/openapi/openroaming_globalreach.yaml +++ b/openapi/openroaming_globalreach.yaml @@ -89,7 +89,7 @@ paths: get: tags: - OpenRoaming-Global Reach - operationId: getOpenRoaminGlobalReachAccountList + operationId: getOpenRoamingGlobalReachAccountList summary: Retrieve account list. parameters: - in: query @@ -132,7 +132,7 @@ paths: get: tags: - OpenRoaming-Global Reach - operationId: getOpenRoaminGlobalReachAccount + operationId: getOpenRoamingGlobalReachAccount summary: Retrieve account information. parameters: - in: path @@ -154,7 +154,7 @@ paths: delete: tags: - OpenRoaming-Global Reach - operationId: deleteOpenRoaminGlobalReachAccount + operationId: deleteOpenRoamingGlobalReachAccount summary: Delete account information. parameters: - in: path @@ -176,7 +176,7 @@ paths: post: tags: - OpenRoaming-Global Reach - operationId: createOpenRoaminGlobalReachAccount + operationId: createOpenRoamingGlobalReachAccount summary: Create account information. parameters: - in: path @@ -203,7 +203,7 @@ paths: put: tags: - OpenRoaming-Global Reach - operationId: modifyOpenRoaminGlobalReachAccount + operationId: modifyOpenRoamingGlobalReachAccount summary: Modify account information. parameters: - in: path @@ -231,7 +231,7 @@ paths: get: tags: - OpenRoaming-Global Reach Certificate - operationId: getOpenRoaminGlobalReachCertificateList + operationId: getOpenRoamingGlobalReachCertificateList summary: Retrieve certificate list. parameters: - in: path @@ -280,17 +280,17 @@ paths: get: tags: - OpenRoaming-Global Reach Certificate - operationId: getOpenRoaminGlobalReachCertificate + operationId: getOpenRoamingGlobalReachCertificate summary: Retrieve certificate information. parameters: - in: path - description: The account name + description: The account name - this is the provisioning ID for the account. Not the GlobalReach ID. name: account schema: type: string required: true - in: path - description: The certificate id + description: The certificate id in provisioning - not the certificate_id from GlobalReach name: id schema: type: string @@ -308,17 +308,17 @@ paths: delete: tags: - OpenRoaming-Global Reach Certificate - operationId: deleteOpenRoaminGlobalReachCertificate + operationId: deleteOpenRoamingGlobalReachCertificate summary: Delete certificate information. parameters: - in: path - description: The account name + description: The account name - this is the provisioning ID for the account. Not the GlobalReach ID. name: account schema: type: string required: true - in: path - description: The certificate id + description: The certificate id in provisioning - not the certificate_id from GlobalReach name: id schema: type: string @@ -336,17 +336,17 @@ paths: post: tags: - OpenRoaming-Global Reach Certificate - operationId: createOpenRoaminGlobalReachCertificate + operationId: createOpenRoamingGlobalReachCertificate summary: Create certificate information. parameters: - in: path - description: The account name + description: The account name - this is the provisioning ID for the account. Not the GlobalReach ID. name: account schema: type: string required: true - in: path - description: The certificate id + description: Must be set to "0" name: id schema: type: string @@ -366,36 +366,3 @@ paths: 404: $ref: '#/components/responses/NotFound' - put: - tags: - - OpenRoaming-Global Reach Certificate - operationId: modifyOpenRoaminGlobalReachCertificate - summary: Modify certificate information. - parameters: - - in: path - description: The account name - name: account - schema: - type: string - required: true - - in: path - description: The certificate id - name: id - schema: - type: string - required: true - requestBody: - content: - application/json: - schema: - $ref: '#/components/schemas/GLBLRAccountInfo' - responses: - 200: - $ref: '#/components/schemas/GLBLRAccountInfo' - 400: - $ref: '#/components/responses/BadRequest' - 403: - $ref: '#/components/responses/Unauthorized' - 404: - $ref: '#/components/responses/NotFound' - diff --git a/src/OpenRoamin_GlobalReach.cpp b/src/OpenRoamin_GlobalReach.cpp index d98aaa7..16bf43b 100644 --- a/src/OpenRoamin_GlobalReach.cpp +++ b/src/OpenRoamin_GlobalReach.cpp @@ -12,11 +12,13 @@ #include #include +#include namespace OpenWifi { int OpenRoaming_GlobalReach::Start() { poco_information(Logger(), "Starting..."); + InitCache(); return 0; } @@ -25,111 +27,150 @@ namespace OpenWifi { poco_information(Logger(), "Stopped..."); } - bool OpenRoaming_GlobalReach::GetAccountInfo( - [[maybe_unused]] const std::string &AccountName, - [[maybe_unused]] ProvObjects::GLBLRAccountInfo &Account) { -/* Poco::URI URI{"https://config.openro.am/v1/config"}; + void OpenRoaming_GlobalReach::InitCache() { - std::string Path(URI.getPathAndQuery()); - - Poco::Net::HTTPRequest Request(Poco::Net::HTTPRequest::HTTP_GET, Path, - Poco::Net::HTTPMessage::HTTP_1_1); - - Request.add("Authorization", "Bearer " + BearerToken); - - Poco::Net::HTTPSClientSession Session(URI.getHost(), URI.getPort()); - Session.setTimeout(Poco::Timespan(10000, 10000)); - - Session.sendRequest(Request); + auto F=[&](const ProvObjects::GLBLRAccountInfo &Info) { + poco_information(Logger(),fmt::format("Adding {} to cache.",Info.info.name)); + if(!Info.privateKey.empty() && !Info.GlobalReachAcctId.empty() ) { + MakeToken(Info.GlobalReachAcctId, Info.privateKey); + } + return true; + }; - Poco::Net::HTTPResponse Response; - std::istream &is = Session.receiveResponse(Response); - Poco::JSON::Parser P; - Result= P.parse(is).extract(); - - std::cout << Response.getStatus() << " : " ; - Result->stringify(std::cout); - std::cout << std::endl; - */ - return true; + StorageService()->GLBLRAccountInfoDB().Iterate(F); } - bool OpenRoaming_GlobalReach::CreateRadsecCertificate( - [[maybe_unused]] const std::string &AccountName, - [[maybe_unused]] ProvObjects::GLBLRCertificateInfo &NewCertificate) { -/* - Poco::URI URI{"https://config.openro.am/v1/radsec/issue"}; - - std::string Path(URI.getPathAndQuery()); - - Poco::Net::HTTPRequest Request(Poco::Net::HTTPRequest::HTTP_POST, Path, - Poco::Net::HTTPMessage::HTTP_1_1); - - Request.add("Authorization", "Bearer " + BearerToken); - - Poco::Net::HTTPSClientSession Session(URI.getHost(), URI.getPort()); - Session.setTimeout(Poco::Timespan(10000, 10000)); - - std::ostringstream os; - Body.stringify(os); - Request.setContentType("application/json"); - Request.setContentLength(os.str().size()); - - auto &body = Session.sendRequest(Request); - body << os.str(); - - Poco::Net::HTTPResponse Response; - std::istream &is = Session.receiveResponse(Response); - Poco::JSON::Parser P; - Result= P.parse(is).extract(); - - std::cout << Response.getStatus() << " : " ; - Result->stringify(std::cout); - std::cout << std::endl; -*/ - return true; + bool OpenRoaming_GlobalReach::CreateRADSECCertificate( + const std::string &GlobalReachAccountId, + const std::string &Name, + const std::string &CSR, + ProvObjects::GLBLRCertificateInfo &NewCertificate) { + + try { + auto BearerToken = MakeToken(GlobalReachAccountId); + Poco::URI URI{"https://config.openro.am/v1/radsec/issue"}; + std::string Path(URI.getPathAndQuery()); + Poco::Net::HTTPRequest Request(Poco::Net::HTTPRequest::HTTP_POST, Path, + Poco::Net::HTTPMessage::HTTP_1_1); + + Request.add("Authorization", "Bearer " + BearerToken); + + Poco::Net::HTTPSClientSession Session(URI.getHost(), URI.getPort()); + Session.setTimeout(Poco::Timespan(10000, 10000)); + Poco::JSON::Object CertRequestBody; + CertRequestBody.set("name", Name); + CertRequestBody.set("csr", CSR); + + std::ostringstream os; + CertRequestBody.stringify(os); + Request.setContentType("application/json"); + Request.setContentLength((long) os.str().size()); + + auto &Body = Session.sendRequest(Request); + Body << os.str(); + + Poco::Net::HTTPResponse Response; + std::istream &is = Session.receiveResponse(Response); + if (Response.getStatus() == Poco::Net::HTTPResponse::HTTP_OK) { + Poco::JSON::Parser P; + auto Result = P.parse(is).extract(); + NewCertificate.csr = Result->get("csr").toString(); + NewCertificate.certificate = Result->get("certificate").toString(); + NewCertificate.name = Result->get("name").toString(); + NewCertificate.certificateChain = Result->get("certificate_chain").toString(); + NewCertificate.certificateId = Result->get("certificate_id").toString(); + NewCertificate.expiresAt = Result->get("expires_at"); + return true; + } + } catch( const Poco::Exception &E) { + poco_error(Logger(),fmt::format("Could not create a new RADSEC certificate: {},{}",E.name(),E.displayText())); + } + return false; } - bool OpenRoaming_GlobalReach::GetRadsecCertificate( - [[maybe_unused]] const std::string &AccountName, - [[maybe_unused]] std::string &CertificateId, - [[maybe_unused]] ProvObjects::GLBLRCertificateInfo &NewCertificate) { - return true; + bool OpenRoaming_GlobalReach::GetRADSECCertificate( + const std::string &GlobalReachAccountId, + std::string &CertificateId, + ProvObjects::GLBLRCertificateInfo &NewCertificate) { + + try { + Poco::URI URI{fmt::format("https://config.openro.am/v1/radsec/cert/{}", CertificateId)}; + + std::string Path(URI.getPathAndQuery()); + + Poco::Net::HTTPRequest Request(Poco::Net::HTTPRequest::HTTP_GET, Path, + Poco::Net::HTTPMessage::HTTP_1_1); + + auto BearerToken = MakeToken(GlobalReachAccountId); + Request.add("Authorization", "Bearer " + BearerToken); + + Poco::Net::HTTPSClientSession Session(URI.getHost(), URI.getPort()); + Session.setTimeout(Poco::Timespan(10000, 10000)); + + Session.sendRequest(Request); + + Poco::Net::HTTPResponse Response; + std::istream &is = Session.receiveResponse(Response); + if (Response.getStatus() == Poco::Net::HTTPResponse::HTTP_OK) { + Poco::JSON::Parser P; + auto Result = P.parse(is).extract(); + NewCertificate.csr = Result->get("csr").toString(); + NewCertificate.certificate = Result->get("certificate").toString(); + NewCertificate.name = Result->get("name").toString(); + NewCertificate.certificateChain = Result->get("certificate_chain").toString(); + NewCertificate.certificateId = Result->get("certificate_id").toString(); + NewCertificate.expiresAt = Result->get("expires_at"); + std::cout << Response.getStatus() << " : "; + Result->stringify(std::cout); + std::cout << std::endl; + return true; + } + } catch( const Poco::Exception &E) { + poco_error(Logger(),fmt::format("Could not retrieve the certificate from GlobalReach: {},{}",E.name(),E.displayText())); + } + return false; } std::string OpenRoaming_GlobalReach::MakeToken(const std::string &GlobalReachAccountId, const std::string &PrivateKey) { - Poco::JWT::Token token; - - token.setType("JWT"); - token.setAlgorithm("ES256"); - token.setIssuedAt(std::time(nullptr)); - - token.payload().set("iss", GlobalReachAccountId); - token.payload().set("iat", (unsigned long) std::time(nullptr)); - - Poco::SharedPtr Key; - auto KeyHash = Utils::ComputeHash(PrivateKey); - auto KeyHint = PrivateKeys_.find(KeyHash); - if(KeyHint!=PrivateKeys_.end()) { - Key = KeyHint->second; - } else { - Poco::TemporaryFile F; - std::ofstream ofs(F.path().c_str(),std::ios_base::trunc|std::ios_base::out|std::ios_base::binary); - ofs << PrivateKey; - ofs.close(); - auto NewKey = Poco::SharedPtr( - new Poco::Crypto::ECKey("", F.path(),"")); - Key = PrivateKeys_[KeyHash] = NewKey; - } + try { + Poco::JWT::Token token; + token.setType("JWT"); + token.setAlgorithm("ES256"); + token.setIssuedAt(std::time(nullptr)); + + token.payload().set("iss", GlobalReachAccountId); + token.payload().set("iat", (unsigned long) std::time(nullptr)); + + Poco::SharedPtr Key; + auto KeyHash = Utils::ComputeHash(PrivateKey); + auto KeyHint = PrivateKeys_.find(GlobalReachAccountId); + if (KeyHint != PrivateKeys_.end() && KeyHint->first == KeyHash) { + Key = KeyHint->second.second; + } else { + if (PrivateKey.empty()) { + return ""; + } + Poco::TemporaryFile F; + std::ofstream ofs(F.path().c_str(), std::ios_base::trunc | std::ios_base::out | std::ios_base::binary); + ofs << PrivateKey; + ofs.close(); + auto NewKey = Poco::SharedPtr( + new Poco::Crypto::ECKey("", F.path(), "")); + Key = NewKey; + PrivateKeys_[GlobalReachAccountId] = std::make_pair(KeyHash, NewKey); + } - Poco::JWT::Signer Signer; - Signer.setECKey(Key); - Signer.addAllAlgorithms(); - return Signer.sign(token, Poco::JWT::Signer::ALGO_ES256); + Poco::JWT::Signer Signer; + Signer.setECKey(Key); + Signer.addAllAlgorithms(); + return Signer.sign(token, Poco::JWT::Signer::ALGO_ES256); + } catch (const Poco::Exception &E) { + poco_error(Logger(),fmt::format("Cannot create a Global Reach token: {},{}",E.name(),E.displayText())); + } + return ""; } - bool OpenRoaming_GlobalReach::VerifyAccount(const std::string &GlobalReachAccountId, const std::string &PrivateKey, [[ - maybe_unused]] std::string &Name) { + bool OpenRoaming_GlobalReach::VerifyAccount(const std::string &GlobalReachAccountId, const std::string &PrivateKey, std::string &Name) { auto BearerToken = MakeToken(GlobalReachAccountId, PrivateKey); Poco::URI URI{"https://config.openro.am/v1/config"}; diff --git a/src/OpenRoamin_GlobalReach.h b/src/OpenRoamin_GlobalReach.h index 3cfea01..6cb009e 100644 --- a/src/OpenRoamin_GlobalReach.h +++ b/src/OpenRoamin_GlobalReach.h @@ -19,15 +19,18 @@ namespace OpenWifi { int Start() override; void Stop() override; - bool GetAccountInfo(const std::string &AccountName, ProvObjects::GLBLRAccountInfo &Account); - bool CreateRadsecCertificate(const std::string &AccountName, ProvObjects::GLBLRCertificateInfo &NewCertificate); - bool GetRadsecCertificate(const std::string &AccountName, std::string & CertificateId, ProvObjects::GLBLRCertificateInfo &NewCertificate); + bool CreateRADSECCertificate(const std::string &AccountName, + const std::string &Name, + const std::string &CSR, + ProvObjects::GLBLRCertificateInfo &NewCertificate); + bool GetRADSECCertificate(const std::string &AccountName, std::string & CertificateId, ProvObjects::GLBLRCertificateInfo &NewCertificate); bool VerifyAccount(const std::string &GlobalReachAccountId, const std::string &PrivateKey, std::string &Name); + void InitCache(); private: - std::string MakeToken(const std::string &GlobalReachAccountId, const std::string &PrivateKey); + std::string MakeToken(const std::string &GlobalReachAccountId, const std::string &PrivateKey=""); - std::map> PrivateKeys_; + std::map>> PrivateKeys_; OpenRoaming_GlobalReach() noexcept : SubSystemServer("OpenRoaming_GlobalReach", "GLBL-REACH", "globalreach") { diff --git a/src/RESTAPI/RESTAPI_openroaming_gr_cert_handler.cpp b/src/RESTAPI/RESTAPI_openroaming_gr_cert_handler.cpp index e7aa4e1..2f39cb8 100644 --- a/src/RESTAPI/RESTAPI_openroaming_gr_cert_handler.cpp +++ b/src/RESTAPI/RESTAPI_openroaming_gr_cert_handler.cpp @@ -3,23 +3,78 @@ // #include "RESTAPI_openroaming_gr_cert_handler.h" +#include namespace OpenWifi { void RESTAPI_openroaming_gr_cert_handler::DoGet() { - return BadRequest(RESTAPI::Errors::NotImplemented); + auto Account = GetBinding("account",""); + auto Id = GetBinding("id",""); + + if(Account.empty() || Id.empty()) { + return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters); + } + + if(!StorageService()->GLBLRAccountInfoDB().Exists("id",Account)) { + return NotFound(); + } + + std::vector Certificates; + DB_.GetRecords(0,1,Certificates,fmt::format(" accountId='{}' and id='{}' ", Account, Id)); + if(Certificates.empty()) { + return NotFound(); + } + return ReturnObject(Certificates[0]); } void RESTAPI_openroaming_gr_cert_handler::DoDelete() { - return BadRequest(RESTAPI::Errors::NotImplemented); + auto Account = GetBinding("account",""); + auto Id = GetBinding("id",""); + if(Account.empty() || Id.empty()) { + return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters); + } + + if(!StorageService()->GLBLRAccountInfoDB().Exists("id",Account)) { + return NotFound(); + } + + DB_.DeleteRecords(fmt::format(" accountId='{}' and id='{}' ", Account, Id)); + return OK(); } void RESTAPI_openroaming_gr_cert_handler::DoPost() { - return BadRequest(RESTAPI::Errors::NotImplemented); - } + auto Account = GetBinding("account",""); + auto Id = GetBinding("id",""); + + if(Account.empty() || Id.empty()) { + return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters); + } + + const auto &RawObject = ParsedBody_; + ProvObjects::GLBLRCertificateInfo NewObject; + if( !NewObject.from_json(RawObject)) { + return BadRequest(OpenWifi::RESTAPI::Errors::InvalidJSONDocument); + } + + if(NewObject.name.empty()) { + return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters); + } + + ProvObjects::GLBLRAccountInfo AccountInfo; + if(!StorageService()->GLBLRAccountInfoDB().GetRecord("id",Account, AccountInfo)) { + return BadRequest(RESTAPI::Errors::InvalidGlobalReachAccount); + } + + if(OpenRoaming_GlobalReach()->CreateRADSECCertificate(AccountInfo.GlobalReachAcctId,NewObject.name,AccountInfo.CSR, NewObject)) { + NewObject.id = MicroServiceCreateUUID(); + NewObject.accountId = Account; + DB_.CreateRecord(NewObject); + ProvObjects::GLBLRCertificateInfo CreatedObject; + DB_.GetRecord("id",NewObject.id,CreatedObject); + return ReturnObject(CreatedObject); + } - void RESTAPI_openroaming_gr_cert_handler::DoPut() { - return BadRequest(RESTAPI::Errors::NotImplemented); + return BadRequest(RESTAPI::Errors::RecordNotCreated); } } // OpenWifi \ No newline at end of file diff --git a/src/RESTAPI/RESTAPI_openroaming_gr_cert_handler.h b/src/RESTAPI/RESTAPI_openroaming_gr_cert_handler.h index c79ad62..d562f78 100644 --- a/src/RESTAPI/RESTAPI_openroaming_gr_cert_handler.h +++ b/src/RESTAPI/RESTAPI_openroaming_gr_cert_handler.h @@ -15,7 +15,6 @@ namespace OpenWifi { : RESTAPIHandler(bindings, L, std::vector{Poco::Net::HTTPRequest::HTTP_GET, Poco::Net::HTTPRequest::HTTP_DELETE, - Poco::Net::HTTPRequest::HTTP_PUT, Poco::Net::HTTPRequest::HTTP_POST, Poco::Net::HTTPRequest::HTTP_OPTIONS}, Server, TransactionId, Internal) {} @@ -25,7 +24,7 @@ namespace OpenWifi { GLBLRCertsDB &DB_ = StorageService()->GLBLRCertsDB(); void DoGet() final; void DoPost() final; - void DoPut() final; + void DoPut() final {}; void DoDelete() final; }; } // namespace OpenWifi From bf20fc27eb6c9b65d5897a7679a7a816fed26770 Mon Sep 17 00:00:00 2001 From: stephb9959 Date: Tue, 12 Sep 2023 11:08:39 -0700 Subject: [PATCH 07/46] https://telecominfraproject.atlassian.net/browse/WIFI-7831 Signed-off-by: stephb9959 --- config-samples/OpenRo.am Test.mobileconfig | 84 ++++++++++++++++++++++ 1 file changed, 84 insertions(+) create mode 100644 config-samples/OpenRo.am Test.mobileconfig diff --git a/config-samples/OpenRo.am Test.mobileconfig b/config-samples/OpenRo.am Test.mobileconfig new file mode 100644 index 0000000..ef44088 --- /dev/null +++ b/config-samples/OpenRo.am Test.mobileconfig @@ -0,0 +1,84 @@ + + + + + PayloadContent + + + AutoJoin + + CaptiveBypass + + DisableAssociationMACRandomization + + DisplayedOperatorName + OpenRo.am + DomainName + openro.am + EAPClientConfiguration + + AcceptEAPTypes + + 21 + + OuterIdentity + anonymous@openro.am + TLSMaximumVersion + 1.2 + TLSMinimumVersion + 1.2 + TTLSInnerAuthentication + MSCHAPv2 + UserName + 420a5371-47d4-4d1d-b234-d17be4e54bb3@openro.am + UserPassword + XaHBCFhgGxi-mCK9XXdQ8 + + EncryptionType + WPA2 + HIDDEN_NETWORK + + IsHotspot + + NAIRealmNames + + openro.am + + PayloadDescription + Configures Wi-Fi settings + PayloadDisplayName + Wi-Fi + PayloadIdentifier + com.apple.wifi.managed.12788EED-2E0C-4370-9411-4EEFC8D9ABB0 + PayloadType + com.apple.wifi.managed + PayloadUUID + 12788EED-2E0C-4370-9411-4EEFC8D9ABB0 + PayloadVersion + 1 + ProxyType + None + RoamingConsortiumOIs + + 5A03BA0000 + + ServiceProviderRoamingEnabled + + + + PayloadDisplayName + OpenRo.am Test + PayloadIdentifier + openroam.44A21054-2F3F-437F-822A-C2F6766A2A23 + PayloadOrganization + OpenRo.am + PayloadRemovalDisallowed + + PayloadType + Configuration + PayloadUUID + 1D460B0F-9311-4FD2-A75D-BADA866BC31C + PayloadVersion + 1 + + From 5390d1fcec32587eafb507461eb8c842ed5917ae Mon Sep 17 00:00:00 2001 From: stephb9959 Date: Tue, 12 Sep 2023 13:51:08 -0700 Subject: [PATCH 08/46] https://telecominfraproject.atlassian.net/browse/WIFI-7831 Signed-off-by: stephb9959 --- openapi/openroaming_globalreach.yaml | 4 ++ .../RESTAPI_openroaming_gr_acct_handler.cpp | 32 +++------- src/RESTObjects/RESTAPI_ProvObjects.cpp | 4 ++ src/RESTObjects/RESTAPI_ProvObjects.h | 2 +- src/framework/ow_constants.h | 1 + src/framework/utils.cpp | 63 +++++++++++++------ src/framework/utils.h | 14 ++++- src/storage/storage_glblraccounts.cpp | 10 ++- src/storage/storage_glblraccounts.h | 2 + 9 files changed, 85 insertions(+), 47 deletions(-) diff --git a/openapi/openroaming_globalreach.yaml b/openapi/openroaming_globalreach.yaml index c71e471..8627d56 100644 --- a/openapi/openroaming_globalreach.yaml +++ b/openapi/openroaming_globalreach.yaml @@ -55,6 +55,10 @@ components: type: string CSR: type: string + CSRPrivateKey: + type: string + CSRPublicKey: + type: string GlobalReachAcctId: type: string diff --git a/src/RESTAPI/RESTAPI_openroaming_gr_acct_handler.cpp b/src/RESTAPI/RESTAPI_openroaming_gr_acct_handler.cpp index ab64484..1578323 100644 --- a/src/RESTAPI/RESTAPI_openroaming_gr_acct_handler.cpp +++ b/src/RESTAPI/RESTAPI_openroaming_gr_acct_handler.cpp @@ -67,7 +67,16 @@ namespace OpenWifi { return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters); } - NewObject.CSR = Utils::CreateX509CSR(NewObject.country,NewObject.province, NewObject.city, NewObject.organization, NewObject.commonName); + Utils::CSRCreationParameters P; + P.Country = NewObject.country; + P.CommonName = NewObject.commonName; + P.Province = NewObject.province; + P.City = NewObject.city; + P.Organization = NewObject.organization; + Utils::CSRCreationResults R; + if(!Utils::CreateX509CSR(P,R)) { + return BadRequest(RESTAPI::Errors::CannotCreateCSR); + } ProvObjects::CreateObjectInfo(RawObject,UserInfo_.userinfo,NewObject.info); @@ -101,27 +110,6 @@ namespace OpenWifi { return BadRequest(OpenWifi::RESTAPI::Errors::InvalidJSONDocument); } - if(RawObject->has("privateKey")) { - if(!Modify.privateKey.empty() && !Utils::VerifyECKey(Modify.privateKey)) { - return BadRequest(RESTAPI::Errors::NotAValidECKey); - } - Existing.privateKey = Modify.privateKey; - } - - std::string GlobalReachName; - if(!OpenRoaming_GlobalReach()->VerifyAccount(Existing.GlobalReachAcctId,Existing.privateKey,GlobalReachName)) { - return BadRequest(RESTAPI::Errors::InvalidGlobalReachAccount); - } - - auto Modified = AssignIfPresent(RawObject,"country",Existing.country) || - AssignIfPresent(RawObject,"commonName",Existing.commonName) || - AssignIfPresent(RawObject,"city",Existing.city) || - AssignIfPresent(RawObject,"province",Existing.province) || - AssignIfPresent(RawObject,"organization",Existing.organization); - if(Modified) { - Existing.CSR = Utils::CreateX509CSR(Existing.country,Existing.province, Existing.city, Existing.organization, Existing.commonName); - } - if(DB_.UpdateRecord("id",Existing.info.id,Existing)) { ProvObjects::GLBLRAccountInfo StoredObject; DB_.GetRecord("id",Existing.info.id,StoredObject); diff --git a/src/RESTObjects/RESTAPI_ProvObjects.cpp b/src/RESTObjects/RESTAPI_ProvObjects.cpp index 6254e4a..cf88234 100644 --- a/src/RESTObjects/RESTAPI_ProvObjects.cpp +++ b/src/RESTObjects/RESTAPI_ProvObjects.cpp @@ -1203,6 +1203,8 @@ namespace OpenWifi::ProvObjects { field_to_json(Obj, "organization", organization); field_to_json(Obj, "commonName", commonName); field_to_json(Obj, "CSR", CSR); + field_to_json(Obj, "CSRPrivateKey", CSRPrivateKey); + field_to_json(Obj, "CSRPublicKey", CSRPublicKey); field_to_json(Obj, "GlobalReachAcctId", GlobalReachAcctId); } @@ -1216,6 +1218,8 @@ namespace OpenWifi::ProvObjects { field_from_json(Obj, "organization", organization); field_from_json(Obj, "commonName", commonName); field_from_json(Obj, "CSR", CSR); + field_from_json(Obj, "CSRPrivateKey", CSRPrivateKey); + field_from_json(Obj, "CSRPublicKey", CSRPublicKey); field_from_json(Obj, "GlobalReachAcctId", GlobalReachAcctId); return true; } catch (const Poco::Exception &E) { diff --git a/src/RESTObjects/RESTAPI_ProvObjects.h b/src/RESTObjects/RESTAPI_ProvObjects.h index 1ef7b27..ec8f449 100644 --- a/src/RESTObjects/RESTAPI_ProvObjects.h +++ b/src/RESTObjects/RESTAPI_ProvObjects.h @@ -751,7 +751,7 @@ namespace OpenWifi::ProvObjects { ObjectInfo info; std::string privateKey; std::string country, province, city, organization, commonName; - std::string CSR; + std::string CSR, CSRPrivateKey, CSRPublicKey; std::string GlobalReachAcctId; void to_json(Poco::JSON::Object &Obj) const; diff --git a/src/framework/ow_constants.h b/src/framework/ow_constants.h index 95da446..eba39c2 100644 --- a/src/framework/ow_constants.h +++ b/src/framework/ow_constants.h @@ -409,6 +409,7 @@ namespace OpenWifi::RESTAPI::Errors { static const struct msg DefFirmwareNameExists { 1172, "Firmware name already exists." }; static const struct msg NotAValidECKey { 1173, "Provided key supplied is not valid." }; static const struct msg InvalidGlobalReachAccount { 1174, "Invalid Global Reach account information (id or key)." }; + static const struct msg CannotCreateCSR { 1175, "Could not create CSR" }; static const struct msg SimulationDoesNotExist { 7000, "Simulation Instance ID does not exist." diff --git a/src/framework/utils.cpp b/src/framework/utils.cpp index ad65bcf..b4486ba 100644 --- a/src/framework/utils.cpp +++ b/src/framework/utils.cpp @@ -609,8 +609,14 @@ namespace OpenWifi::Utils { return DT.timestamp().epochTime(); } - std::string CreateX509CSR(const std::string &Country, const std::string &Province, const std::string &City, - const std::string &Organization, const std::string &CommonName, int bits ) { + static std::string FileToString(const std::string &Filename) { + std::ifstream ifs(Filename.c_str(),std::ios_base::in|std::ios_base::binary); + std::ostringstream os; + Poco::StreamCopier::copyStream(ifs,os); + return os.str(); + } + + bool CreateX509CSR(const CSRCreationParameters & Parameters, CSRCreationResults & Results) { int ret = 0; RSA *r = nullptr; BIGNUM *bne = nullptr; @@ -622,21 +628,23 @@ namespace OpenWifi::Utils { X509_NAME *x509_name = nullptr; EVP_PKEY *pKey = nullptr; // RSA *tem = nullptr; - BIO *out = nullptr; // BIO *bio_err = nullptr; - const char *szCountry = Country.c_str(); - const char *szProvince = Province.c_str(); - const char *szCity = City.c_str(); - const char *szOrganization = Organization.c_str(); - const char *szCommon = CommonName.c_str(); + const char *szCountry = Parameters.Country.c_str(); + const char *szProvince = Parameters.Province.c_str(); + const char *szCity = Parameters.City.c_str(); + const char *szOrganization = Parameters.Organization.c_str(); + const char *szCommon = Parameters.CommonName.c_str(); - Poco::TemporaryFile CsrPath; + Poco::TemporaryFile CsrPath, PubKey, PrivateKey; std::string Result; std::ifstream ifs; std::ostringstream ss; + BIO *bp_public = nullptr, + *bp_private = nullptr, + *bp_csr = nullptr; - // 1. generate rsa key + // 1. generate rsa key bne = BN_new(); ret = BN_set_word(bne,e); if(ret != 1){ @@ -644,11 +652,23 @@ namespace OpenWifi::Utils { } r = RSA_new(); - ret = RSA_generate_key_ex(r, bits, bne, nullptr); + ret = RSA_generate_key_ex(r, Parameters.bits, bne, nullptr); if(ret != 1){ goto free_all; } + bp_public = BIO_new_file(PubKey.path().c_str(), "w+"); + ret = PEM_write_bio_RSAPublicKey(bp_public, r); + if(ret != 1) { + goto free_all; + } + + bp_private = BIO_new_file(PrivateKey.path().c_str(), "w+"); + ret = PEM_write_bio_RSAPrivateKey(bp_private, r, NULL, NULL, 0, NULL, NULL); + if(ret != 1) { + goto free_all; + } + // 2. set version of x509 req x509_req = X509_REQ_new(); ret = X509_REQ_set_version(x509_req, nVersion); @@ -700,22 +720,25 @@ namespace OpenWifi::Utils { goto free_all; } - out = BIO_new_file(CsrPath.path().c_str(),"w"); - ret = PEM_write_bio_X509_REQ(out, x509_req); + bp_csr = BIO_new_file(CsrPath.path().c_str(),"w"); + ret = PEM_write_bio_X509_REQ(bp_csr, x509_req); - ifs.open(CsrPath.path().c_str(),std::ios_base::binary|std::ios_base::in); - Poco::StreamCopier::copyStream(ifs,ss); - ifs.close(); - Result = ss.str(); // 6. free - free_all: + free_all: X509_REQ_free(x509_req); - BIO_free_all(out); + BIO_free_all(bp_csr); + BIO_free_all(bp_public); + BIO_free_all(bp_private); EVP_PKEY_free(pKey); BN_free(bne); + if(ret==1) { + Results.CSR = FileToString(CsrPath.path()); + Results.PrivateKey = FileToString(PrivateKey.path()); + Results.PublicKey = FileToString(PubKey.path()); + } - return Result; + return ret; } bool VerifyECKey(const std::string &key) { diff --git a/src/framework/utils.h b/src/framework/utils.h index 2580b78..9a9c939 100644 --- a/src/framework/utils.h +++ b/src/framework/utils.h @@ -247,7 +247,17 @@ namespace OpenWifi::Utils { return count; } - std::string CreateX509CSR(const std::string &Country, const std::string &Province, const std::string &City, - const std::string &Organization, const std::string &CommonName, int bits=2048); + struct CSRCreationParameters { + std::string Country, Province, City, + Organization, CommonName; + int bits=2048; + }; + + struct CSRCreationResults { + std::string CSR, PublicKey, PrivateKey; + }; + + bool CreateX509CSR(const CSRCreationParameters & Parameters, CSRCreationResults & Results); + bool VerifyECKey(const std::string &key); } // namespace OpenWifi::Utils diff --git a/src/storage/storage_glblraccounts.cpp b/src/storage/storage_glblraccounts.cpp index 37210b0..2d0bee7 100644 --- a/src/storage/storage_glblraccounts.cpp +++ b/src/storage/storage_glblraccounts.cpp @@ -25,6 +25,8 @@ namespace OpenWifi { ORM::Field{"organization", ORM::FieldType::FT_TEXT}, ORM::Field{"commonName", ORM::FieldType::FT_TEXT}, ORM::Field{"CSR", ORM::FieldType::FT_TEXT}, + ORM::Field{"CSRPrivateKey", ORM::FieldType::FT_TEXT}, + ORM::Field{"CSRPublicKey", ORM::FieldType::FT_TEXT}, ORM::Field{"GlobalReachAcctId", ORM::FieldType::FT_TEXT} }; @@ -68,7 +70,9 @@ void ORM::DB(); Out.commonName = In.get<11>(); Out.CSR = In.get<12>(); - Out.GlobalReachAcctId = In.get<13>(); + Out.CSRPrivateKey = In.get<13>(); + Out.CSRPublicKey = In.get<14>(); + Out.GlobalReachAcctId = In.get<15>(); } template <> @@ -87,5 +91,7 @@ void ORM::DB(In.organization); Out.set<11>(In.commonName); Out.set<12>(In.CSR); - Out.set<13>(In.GlobalReachAcctId); + Out.set<13>(In.CSRPrivateKey); + Out.set<14>(In.CSRPublicKey); + Out.set<15>(In.GlobalReachAcctId); } diff --git a/src/storage/storage_glblraccounts.h b/src/storage/storage_glblraccounts.h index dc0f8d3..cfb0a69 100644 --- a/src/storage/storage_glblraccounts.h +++ b/src/storage/storage_glblraccounts.h @@ -19,6 +19,8 @@ namespace OpenWifi { std::string, std::string, std::string, + std::string, + std::string, std::string> GLBLRAccountsDBRecordType; From 797a7f20bc0596b4e571951966d6d986c1bfded8 Mon Sep 17 00:00:00 2001 From: stephb9959 Date: Tue, 12 Sep 2023 14:24:14 -0700 Subject: [PATCH 09/46] https://telecominfraproject.atlassian.net/browse/WIFI-7831 Signed-off-by: stephb9959 --- src/RESTAPI/RESTAPI_openroaming_gr_acct_handler.cpp | 10 +++++++--- test_scripts/curl/cli | 13 +++++++++++++ 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/src/RESTAPI/RESTAPI_openroaming_gr_acct_handler.cpp b/src/RESTAPI/RESTAPI_openroaming_gr_acct_handler.cpp index 1578323..8d21fff 100644 --- a/src/RESTAPI/RESTAPI_openroaming_gr_acct_handler.cpp +++ b/src/RESTAPI/RESTAPI_openroaming_gr_acct_handler.cpp @@ -8,7 +8,7 @@ namespace OpenWifi { void RESTAPI_openroaming_gr_acct_handler::DoGet() { - auto Account = GetBinding("account",""); + auto Account = GetBinding("id",""); if(Account.empty()) { return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters); } @@ -21,7 +21,7 @@ namespace OpenWifi { } void RESTAPI_openroaming_gr_acct_handler::DoDelete() { - auto Account = GetBinding("account",""); + auto Account = GetBinding("id",""); if(Account.empty()) { return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters); } @@ -38,7 +38,7 @@ namespace OpenWifi { } void RESTAPI_openroaming_gr_acct_handler::DoPost() { - auto Account = GetBinding("account",""); + auto Account = GetBinding("id",""); if(Account.empty()) { return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters); } @@ -78,6 +78,10 @@ namespace OpenWifi { return BadRequest(RESTAPI::Errors::CannotCreateCSR); } + NewObject.CSR = R.CSR; + NewObject.CSRPublicKey = R.PublicKey; + NewObject.CSRPrivateKey = R.PrivateKey; + ProvObjects::CreateObjectInfo(RawObject,UserInfo_.userinfo,NewObject.info); if(DB_.CreateRecord(NewObject)) { diff --git a/test_scripts/curl/cli b/test_scripts/curl/cli index a45f37e..98e5f58 100755 --- a/test_scripts/curl/cli +++ b/test_scripts/curl/cli @@ -617,6 +617,18 @@ getsystemconfiguration() { jq < ${result_file} } +creategraccount() { + payload="{ \"name\" : \"Test account\" , \"country\" : \"CA\", \"province\" : \"BC\" , \"city\" : \"Vancouver\", \"organization\" : \"Arilia Wireless Inc.\", \"commonName\" : \"arilia.com\", \"GlobalReachAcctId\" : \"bd63aaa7-b14d-4cdb-85ae-8de6cf2cfa31\", \"privateKey\" : \"-----BEGIN PRIVATE KEY-----MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgl1FpARtuOtw1F9sR2DD82jh6sZFGRn619IY0rmNIFEuhRANCAATB7ji6OF/+heGRCocgVNhw4QGvaL9Kp8F6ZqqZ3aMewRMOfzi3TQaXN12FNBsvXnptx5vk8GAzZk6UAzzvMBVK-----END PRIVATE KEY-----\" }" + echo $payload | jq + + curl ${FLAGS} -X POST "https://${OWPROV}/api/v1/openroaming/globalreach/account/0" \ + -H "Content-Type: application/json" \ + -H "Authorization: Bearer ${token}" \ + -H "Accept: application/json" \ + -d "$payload" > ${result_file} + jq < ${result_file} +} + shopt -s nocasematch case "$1" in "login") login; echo "You are logged in..." ; logout ;; @@ -673,6 +685,7 @@ case "$1" in "deleteoverride") login; deleteoverride "$2"; logout;; "venueupgraderevisions") login; venueupgraderevisions "$2"; logout;; "getsystemconfiguration") login; getsystemconfiguration "$2"; logout;; + "creategraccount") login; creategraccount ; logout;; "getvenuesperrrm") login; getvenuesperrrm "$2"; logout;; *) help ;; esac From 4fecee46ac40f1079f0ec1b340eae7178d760da0 Mon Sep 17 00:00:00 2001 From: stephb9959 Date: Tue, 12 Sep 2023 14:49:12 -0700 Subject: [PATCH 10/46] https://telecominfraproject.atlassian.net/browse/WIFI-7831 Signed-off-by: stephb9959 --- src/OpenRoamin_GlobalReach.cpp | 12 ++++++++++ test_scripts/curl/cli | 43 +++++++++++++++++++++++++++++++--- 2 files changed, 52 insertions(+), 3 deletions(-) diff --git a/src/OpenRoamin_GlobalReach.cpp b/src/OpenRoamin_GlobalReach.cpp index 16bf43b..8bb7c72 100644 --- a/src/OpenRoamin_GlobalReach.cpp +++ b/src/OpenRoamin_GlobalReach.cpp @@ -47,30 +47,40 @@ namespace OpenWifi { ProvObjects::GLBLRCertificateInfo &NewCertificate) { try { + std::cout << __LINE__ << std::endl; auto BearerToken = MakeToken(GlobalReachAccountId); Poco::URI URI{"https://config.openro.am/v1/radsec/issue"}; std::string Path(URI.getPathAndQuery()); + std::cout << __LINE__ << std::endl; Poco::Net::HTTPRequest Request(Poco::Net::HTTPRequest::HTTP_POST, Path, Poco::Net::HTTPMessage::HTTP_1_1); + std::cout << __LINE__ << std::endl; Request.add("Authorization", "Bearer " + BearerToken); + std::cout << __LINE__ << std::endl; Poco::Net::HTTPSClientSession Session(URI.getHost(), URI.getPort()); Session.setTimeout(Poco::Timespan(10000, 10000)); + std::cout << __LINE__ << std::endl; Poco::JSON::Object CertRequestBody; CertRequestBody.set("name", Name); CertRequestBody.set("csr", CSR); + std::cout << __LINE__ << std::endl; std::ostringstream os; + std::cout << __LINE__ << std::endl; CertRequestBody.stringify(os); Request.setContentType("application/json"); Request.setContentLength((long) os.str().size()); + std::cout << __LINE__ << std::endl; auto &Body = Session.sendRequest(Request); Body << os.str(); + std::cout << __LINE__ << std::endl; Poco::Net::HTTPResponse Response; std::istream &is = Session.receiveResponse(Response); + std::cout << __LINE__ << std::endl; if (Response.getStatus() == Poco::Net::HTTPResponse::HTTP_OK) { Poco::JSON::Parser P; auto Result = P.parse(is).extract(); @@ -80,8 +90,10 @@ namespace OpenWifi { NewCertificate.certificateChain = Result->get("certificate_chain").toString(); NewCertificate.certificateId = Result->get("certificate_id").toString(); NewCertificate.expiresAt = Result->get("expires_at"); + std::cout << __LINE__ << std::endl; return true; } + std::cout << Response.getStatus() << std::endl; } catch( const Poco::Exception &E) { poco_error(Logger(),fmt::format("Could not create a new RADSEC certificate: {},{}",E.name(),E.displayText())); } diff --git a/test_scripts/curl/cli b/test_scripts/curl/cli index 98e5f58..b0fe918 100755 --- a/test_scripts/curl/cli +++ b/test_scripts/curl/cli @@ -618,9 +618,7 @@ getsystemconfiguration() { } creategraccount() { - payload="{ \"name\" : \"Test account\" , \"country\" : \"CA\", \"province\" : \"BC\" , \"city\" : \"Vancouver\", \"organization\" : \"Arilia Wireless Inc.\", \"commonName\" : \"arilia.com\", \"GlobalReachAcctId\" : \"bd63aaa7-b14d-4cdb-85ae-8de6cf2cfa31\", \"privateKey\" : \"-----BEGIN PRIVATE KEY-----MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgl1FpARtuOtw1F9sR2DD82jh6sZFGRn619IY0rmNIFEuhRANCAATB7ji6OF/+heGRCocgVNhw4QGvaL9Kp8F6ZqqZ3aMewRMOfzi3TQaXN12FNBsvXnptx5vk8GAzZk6UAzzvMBVK-----END PRIVATE KEY-----\" }" - echo $payload | jq - + payload="{ \"name\" : \"Test account\" , \"country\" : \"CA\", \"province\" : \"BC\" , \"city\" : \"Vancouver\", \"organization\" : \"Arilia Wireless Inc.\", \"commonName\" : \"arilia.com\", \"GlobalReachAcctId\" : \"bd63aaa7-b14d-4cdb-85ae-8de6cf2cfa31\", \"privateKey\" : \"-----BEGIN PRIVATE KEY-----\nMIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgl1FpARtuOtw1F9sR2DD82jh6sZFGRn619IY0rmNIFEuhRANCAATB7ji6OF/+heGRCocgVNhw4QGvaL9Kp8F6ZqqZ3aMewRMOfzi3TQaXN12FNBsvXnptx5vk8GAzZk6UAzzvMBVK\n-----END PRIVATE KEY-----\" }" curl ${FLAGS} -X POST "https://${OWPROV}/api/v1/openroaming/globalreach/account/0" \ -H "Content-Type: application/json" \ -H "Authorization: Bearer ${token}" \ @@ -629,6 +627,41 @@ creategraccount() { jq < ${result_file} } +getgraccount() { + curl ${FLAGS} -X GET "https://${OWPROV}/api/v1/openroaming/globalreach/account/$1" \ + -H "Content-Type: application/json" \ + -H "Authorization: Bearer ${token}" \ + -H "Accept: application/json" > ${result_file} + jq < ${result_file} +} + +deletegraccount() { + curl ${FLAGS} -X DELETE "https://${OWPROV}/api/v1/openroaming/globalreach/account/$1" \ + -H "Content-Type: application/json" \ + -H "Authorization: Bearer ${token}" \ + -H "Accept: application/json" > ${result_file} + jq < ${result_file} +} + +getgraccounts() { + curl ${FLAGS} -X GET "https://${OWPROV}/api/v1/openroaming/globalreach/accounts" \ + -H "Content-Type: application/json" \ + -H "Authorization: Bearer ${token}" \ + -H "Accept: application/json" > ${result_file} + jq < ${result_file} +} + +creategrcert() { + payload="{ \"name\" : \"$2\" }" + curl ${FLAGS} -X POST "https://${OWPROV}/api/v1/openroaming/globalreach/certificate/$1/0" \ + -H "Content-Type: application/json" \ + -H "Authorization: Bearer ${token}" \ + -H "Accept: application/json" \ + -d "$payload" > ${result_file} + jq < ${result_file} + +} + shopt -s nocasematch case "$1" in "login") login; echo "You are logged in..." ; logout ;; @@ -686,6 +719,10 @@ case "$1" in "venueupgraderevisions") login; venueupgraderevisions "$2"; logout;; "getsystemconfiguration") login; getsystemconfiguration "$2"; logout;; "creategraccount") login; creategraccount ; logout;; + "getgraccount") login; getgraccount "$2"; logout;; + "getgraccounts") login; getgraccounts ; logout;; + "creategrcert") login; creategrcert "$2" "$3"; logout;; + "deletegraccount") login; deletegraccount "$2"; logout;; "getvenuesperrrm") login; getvenuesperrrm "$2"; logout;; *) help ;; esac From 5660689d687bcc9328f6683f50b11c37fd22da37 Mon Sep 17 00:00:00 2001 From: stephb9959 Date: Tue, 12 Sep 2023 14:51:54 -0700 Subject: [PATCH 11/46] https://telecominfraproject.atlassian.net/browse/WIFI-7831 Signed-off-by: stephb9959 --- src/OpenRoamin_GlobalReach.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/OpenRoamin_GlobalReach.cpp b/src/OpenRoamin_GlobalReach.cpp index 8bb7c72..752401a 100644 --- a/src/OpenRoamin_GlobalReach.cpp +++ b/src/OpenRoamin_GlobalReach.cpp @@ -93,7 +93,11 @@ namespace OpenWifi { std::cout << __LINE__ << std::endl; return true; } - std::cout << Response.getStatus() << std::endl; + Poco::JSON::Parser P; + std::ostringstream oos; + auto Result = P.parse(is).extract(); + Result->stringify(oos); + std::cout << oos.str() << std::endl; } catch( const Poco::Exception &E) { poco_error(Logger(),fmt::format("Could not create a new RADSEC certificate: {},{}",E.name(),E.displayText())); } From 1d14018470d266e067a821d77fd569ed4ed34fbb Mon Sep 17 00:00:00 2001 From: stephb9959 Date: Tue, 12 Sep 2023 14:59:44 -0700 Subject: [PATCH 12/46] https://telecominfraproject.atlassian.net/browse/WIFI-7831 Signed-off-by: stephb9959 --- src/OpenRoamin_GlobalReach.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/OpenRoamin_GlobalReach.cpp b/src/OpenRoamin_GlobalReach.cpp index 752401a..f7b53d5 100644 --- a/src/OpenRoamin_GlobalReach.cpp +++ b/src/OpenRoamin_GlobalReach.cpp @@ -32,7 +32,9 @@ namespace OpenWifi { auto F=[&](const ProvObjects::GLBLRAccountInfo &Info) { poco_information(Logger(),fmt::format("Adding {} to cache.",Info.info.name)); if(!Info.privateKey.empty() && !Info.GlobalReachAcctId.empty() ) { + DBGLINE MakeToken(Info.GlobalReachAcctId, Info.privateKey); + DBGLINE } return true; }; @@ -160,10 +162,13 @@ namespace OpenWifi { Poco::SharedPtr Key; auto KeyHash = Utils::ComputeHash(PrivateKey); auto KeyHint = PrivateKeys_.find(GlobalReachAccountId); + DBGLINE if (KeyHint != PrivateKeys_.end() && KeyHint->first == KeyHash) { + DBGLINE Key = KeyHint->second.second; } else { if (PrivateKey.empty()) { + DBGLINE return ""; } Poco::TemporaryFile F; @@ -174,6 +179,7 @@ namespace OpenWifi { new Poco::Crypto::ECKey("", F.path(), "")); Key = NewKey; PrivateKeys_[GlobalReachAccountId] = std::make_pair(KeyHash, NewKey); + DBGLINE } Poco::JWT::Signer Signer; From 043c167d3d49c9029d10e9209b7397250b9abbba Mon Sep 17 00:00:00 2001 From: stephb9959 Date: Tue, 12 Sep 2023 15:04:43 -0700 Subject: [PATCH 13/46] https://telecominfraproject.atlassian.net/browse/WIFI-7831 Signed-off-by: stephb9959 --- src/OpenRoamin_GlobalReach.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/OpenRoamin_GlobalReach.cpp b/src/OpenRoamin_GlobalReach.cpp index f7b53d5..71e403a 100644 --- a/src/OpenRoamin_GlobalReach.cpp +++ b/src/OpenRoamin_GlobalReach.cpp @@ -163,7 +163,7 @@ namespace OpenWifi { auto KeyHash = Utils::ComputeHash(PrivateKey); auto KeyHint = PrivateKeys_.find(GlobalReachAccountId); DBGLINE - if (KeyHint != PrivateKeys_.end() && KeyHint->first == KeyHash) { + if (KeyHint != PrivateKeys_.end() && KeyHint->second.first == KeyHash) { DBGLINE Key = KeyHint->second.second; } else { From 19528133a3bc0eaf0dceae16485697646a63cecb Mon Sep 17 00:00:00 2001 From: stephb9959 Date: Tue, 12 Sep 2023 15:09:18 -0700 Subject: [PATCH 14/46] https://telecominfraproject.atlassian.net/browse/WIFI-7831 Signed-off-by: stephb9959 --- src/OpenRoamin_GlobalReach.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/OpenRoamin_GlobalReach.cpp b/src/OpenRoamin_GlobalReach.cpp index 71e403a..dec7528 100644 --- a/src/OpenRoamin_GlobalReach.cpp +++ b/src/OpenRoamin_GlobalReach.cpp @@ -32,9 +32,7 @@ namespace OpenWifi { auto F=[&](const ProvObjects::GLBLRAccountInfo &Info) { poco_information(Logger(),fmt::format("Adding {} to cache.",Info.info.name)); if(!Info.privateKey.empty() && !Info.GlobalReachAcctId.empty() ) { - DBGLINE MakeToken(Info.GlobalReachAcctId, Info.privateKey); - DBGLINE } return true; }; @@ -49,7 +47,7 @@ namespace OpenWifi { ProvObjects::GLBLRCertificateInfo &NewCertificate) { try { - std::cout << __LINE__ << std::endl; + std::cout << __LINE__ << ":" << GlobalReachAccountId << std::endl; auto BearerToken = MakeToken(GlobalReachAccountId); Poco::URI URI{"https://config.openro.am/v1/radsec/issue"}; std::string Path(URI.getPathAndQuery()); From cb7ad596e2fdc7d4de5d74a5248738acc87869dd Mon Sep 17 00:00:00 2001 From: stephb9959 Date: Tue, 12 Sep 2023 15:12:15 -0700 Subject: [PATCH 15/46] https://telecominfraproject.atlassian.net/browse/WIFI-7831 Signed-off-by: stephb9959 --- src/OpenRoamin_GlobalReach.cpp | 17 ++--------------- 1 file changed, 2 insertions(+), 15 deletions(-) diff --git a/src/OpenRoamin_GlobalReach.cpp b/src/OpenRoamin_GlobalReach.cpp index dec7528..690eb7a 100644 --- a/src/OpenRoamin_GlobalReach.cpp +++ b/src/OpenRoamin_GlobalReach.cpp @@ -51,36 +51,26 @@ namespace OpenWifi { auto BearerToken = MakeToken(GlobalReachAccountId); Poco::URI URI{"https://config.openro.am/v1/radsec/issue"}; std::string Path(URI.getPathAndQuery()); - std::cout << __LINE__ << std::endl; Poco::Net::HTTPRequest Request(Poco::Net::HTTPRequest::HTTP_POST, Path, Poco::Net::HTTPMessage::HTTP_1_1); - std::cout << __LINE__ << std::endl; - Request.add("Authorization", "Bearer " + BearerToken); - std::cout << __LINE__ << std::endl; Poco::Net::HTTPSClientSession Session(URI.getHost(), URI.getPort()); Session.setTimeout(Poco::Timespan(10000, 10000)); - std::cout << __LINE__ << std::endl; Poco::JSON::Object CertRequestBody; CertRequestBody.set("name", Name); CertRequestBody.set("csr", CSR); - std::cout << __LINE__ << std::endl; std::ostringstream os; - std::cout << __LINE__ << std::endl; CertRequestBody.stringify(os); Request.setContentType("application/json"); Request.setContentLength((long) os.str().size()); - std::cout << __LINE__ << std::endl; auto &Body = Session.sendRequest(Request); Body << os.str(); - std::cout << __LINE__ << std::endl; Poco::Net::HTTPResponse Response; std::istream &is = Session.receiveResponse(Response); - std::cout << __LINE__ << std::endl; if (Response.getStatus() == Poco::Net::HTTPResponse::HTTP_OK) { Poco::JSON::Parser P; auto Result = P.parse(is).extract(); @@ -90,7 +80,6 @@ namespace OpenWifi { NewCertificate.certificateChain = Result->get("certificate_chain").toString(); NewCertificate.certificateId = Result->get("certificate_id").toString(); NewCertificate.expiresAt = Result->get("expires_at"); - std::cout << __LINE__ << std::endl; return true; } Poco::JSON::Parser P; @@ -108,6 +97,7 @@ namespace OpenWifi { const std::string &GlobalReachAccountId, std::string &CertificateId, ProvObjects::GLBLRCertificateInfo &NewCertificate) { + std::cout << __LINE__ << ":" << GlobalReachAccountId << std::endl; try { Poco::URI URI{fmt::format("https://config.openro.am/v1/radsec/cert/{}", CertificateId)}; @@ -153,6 +143,7 @@ namespace OpenWifi { token.setType("JWT"); token.setAlgorithm("ES256"); token.setIssuedAt(std::time(nullptr)); + std::cout << __LINE__ << ":" << GlobalReachAccountId << std::endl; token.payload().set("iss", GlobalReachAccountId); token.payload().set("iat", (unsigned long) std::time(nullptr)); @@ -160,13 +151,10 @@ namespace OpenWifi { Poco::SharedPtr Key; auto KeyHash = Utils::ComputeHash(PrivateKey); auto KeyHint = PrivateKeys_.find(GlobalReachAccountId); - DBGLINE if (KeyHint != PrivateKeys_.end() && KeyHint->second.first == KeyHash) { - DBGLINE Key = KeyHint->second.second; } else { if (PrivateKey.empty()) { - DBGLINE return ""; } Poco::TemporaryFile F; @@ -177,7 +165,6 @@ namespace OpenWifi { new Poco::Crypto::ECKey("", F.path(), "")); Key = NewKey; PrivateKeys_[GlobalReachAccountId] = std::make_pair(KeyHash, NewKey); - DBGLINE } Poco::JWT::Signer Signer; From 74de9188d2e8bce97dabb6f1c808252ae7de6ce7 Mon Sep 17 00:00:00 2001 From: stephb9959 Date: Tue, 12 Sep 2023 15:14:37 -0700 Subject: [PATCH 16/46] https://telecominfraproject.atlassian.net/browse/WIFI-7831 Signed-off-by: stephb9959 --- src/OpenRoamin_GlobalReach.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/OpenRoamin_GlobalReach.cpp b/src/OpenRoamin_GlobalReach.cpp index 690eb7a..de2aa56 100644 --- a/src/OpenRoamin_GlobalReach.cpp +++ b/src/OpenRoamin_GlobalReach.cpp @@ -143,7 +143,7 @@ namespace OpenWifi { token.setType("JWT"); token.setAlgorithm("ES256"); token.setIssuedAt(std::time(nullptr)); - std::cout << __LINE__ << ":" << GlobalReachAccountId << std::endl; + std::cout << __LINE__ << ":" << GlobalReachAccountId << " : " << PrivateKeys_.size() << std::endl; token.payload().set("iss", GlobalReachAccountId); token.payload().set("iat", (unsigned long) std::time(nullptr)); From 8a12becd2bc2695a5b1c39194d67fd002c4b0686 Mon Sep 17 00:00:00 2001 From: stephb9959 Date: Tue, 12 Sep 2023 15:18:18 -0700 Subject: [PATCH 17/46] https://telecominfraproject.atlassian.net/browse/WIFI-7831 Signed-off-by: stephb9959 --- src/OpenRoamin_GlobalReach.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/OpenRoamin_GlobalReach.cpp b/src/OpenRoamin_GlobalReach.cpp index de2aa56..acfc2e4 100644 --- a/src/OpenRoamin_GlobalReach.cpp +++ b/src/OpenRoamin_GlobalReach.cpp @@ -151,7 +151,7 @@ namespace OpenWifi { Poco::SharedPtr Key; auto KeyHash = Utils::ComputeHash(PrivateKey); auto KeyHint = PrivateKeys_.find(GlobalReachAccountId); - if (KeyHint != PrivateKeys_.end() && KeyHint->second.first == KeyHash) { + if (KeyHint != PrivateKeys_.end() && PrivateKey.empty() ) { Key = KeyHint->second.second; } else { if (PrivateKey.empty()) { From 3dadc191d5f95fb228f12a318dc831d05aa48a69 Mon Sep 17 00:00:00 2001 From: stephb9959 Date: Tue, 12 Sep 2023 23:00:56 -0700 Subject: [PATCH 18/46] https://telecominfraproject.atlassian.net/browse/WIFI-7831 Signed-off-by: stephb9959 --- src/OpenRoamin_GlobalReach.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/OpenRoamin_GlobalReach.cpp b/src/OpenRoamin_GlobalReach.cpp index acfc2e4..4d78cce 100644 --- a/src/OpenRoamin_GlobalReach.cpp +++ b/src/OpenRoamin_GlobalReach.cpp @@ -89,6 +89,7 @@ namespace OpenWifi { std::cout << oos.str() << std::endl; } catch( const Poco::Exception &E) { poco_error(Logger(),fmt::format("Could not create a new RADSEC certificate: {},{}",E.name(),E.displayText())); + std::cout << E.name() << " : " << E.displayText() << std::endl; } return false; } From 4b78e64eb52d5a474c63064a5e25d77c8cc94f43 Mon Sep 17 00:00:00 2001 From: stephb9959 Date: Tue, 12 Sep 2023 23:12:05 -0700 Subject: [PATCH 19/46] https://telecominfraproject.atlassian.net/browse/WIFI-7831 Signed-off-by: stephb9959 --- src/OpenRoamin_GlobalReach.cpp | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/src/OpenRoamin_GlobalReach.cpp b/src/OpenRoamin_GlobalReach.cpp index 4d78cce..2797b4c 100644 --- a/src/OpenRoamin_GlobalReach.cpp +++ b/src/OpenRoamin_GlobalReach.cpp @@ -10,7 +10,7 @@ #include #include #include - +#include #include #include @@ -74,6 +74,7 @@ namespace OpenWifi { if (Response.getStatus() == Poco::Net::HTTPResponse::HTTP_OK) { Poco::JSON::Parser P; auto Result = P.parse(is).extract(); + RESTAPI:: NewCertificate.csr = Result->get("csr").toString(); NewCertificate.certificate = Result->get("certificate").toString(); NewCertificate.name = Result->get("name").toString(); @@ -121,12 +122,10 @@ namespace OpenWifi { if (Response.getStatus() == Poco::Net::HTTPResponse::HTTP_OK) { Poco::JSON::Parser P; auto Result = P.parse(is).extract(); - NewCertificate.csr = Result->get("csr").toString(); - NewCertificate.certificate = Result->get("certificate").toString(); - NewCertificate.name = Result->get("name").toString(); - NewCertificate.certificateChain = Result->get("certificate_chain").toString(); - NewCertificate.certificateId = Result->get("certificate_id").toString(); - NewCertificate.expiresAt = Result->get("expires_at"); + RESTAPIHandler::AssignIfPresent(Result,"certificate",NewCertificate.certificate); + RESTAPIHandler::AssignIfPresent(Result,"certificate_chain",NewCertificate.certificateChain); + RESTAPIHandler::AssignIfPresent(Result,"certificate_id",NewCertificate.certificateId); + RESTAPIHandler::AssignIfPresent(Result,"expires_at",NewCertificate.expiresAt); std::cout << Response.getStatus() << " : "; Result->stringify(std::cout); std::cout << std::endl; From 87653e1e4bc867845c38d65f9c859a806bcf46cd Mon Sep 17 00:00:00 2001 From: stephb9959 Date: Tue, 12 Sep 2023 23:13:30 -0700 Subject: [PATCH 20/46] https://telecominfraproject.atlassian.net/browse/WIFI-7831 Signed-off-by: stephb9959 --- src/OpenRoamin_GlobalReach.cpp | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/src/OpenRoamin_GlobalReach.cpp b/src/OpenRoamin_GlobalReach.cpp index 2797b4c..c7ec0ce 100644 --- a/src/OpenRoamin_GlobalReach.cpp +++ b/src/OpenRoamin_GlobalReach.cpp @@ -74,13 +74,10 @@ namespace OpenWifi { if (Response.getStatus() == Poco::Net::HTTPResponse::HTTP_OK) { Poco::JSON::Parser P; auto Result = P.parse(is).extract(); - RESTAPI:: - NewCertificate.csr = Result->get("csr").toString(); - NewCertificate.certificate = Result->get("certificate").toString(); - NewCertificate.name = Result->get("name").toString(); - NewCertificate.certificateChain = Result->get("certificate_chain").toString(); - NewCertificate.certificateId = Result->get("certificate_id").toString(); - NewCertificate.expiresAt = Result->get("expires_at"); + RESTAPIHandler::AssignIfPresent(Result,"certificate",NewCertificate.certificate); + RESTAPIHandler::AssignIfPresent(Result,"certificate_chain",NewCertificate.certificateChain); + RESTAPIHandler::AssignIfPresent(Result,"certificate_id",NewCertificate.certificateId); + RESTAPIHandler::AssignIfPresent(Result,"expires_at",NewCertificate.expiresAt); return true; } Poco::JSON::Parser P; From f9af051ce919a9137e438af8a92a0ad48ddcefb7 Mon Sep 17 00:00:00 2001 From: stephb9959 Date: Tue, 12 Sep 2023 23:15:59 -0700 Subject: [PATCH 21/46] https://telecominfraproject.atlassian.net/browse/WIFI-7831 Signed-off-by: stephb9959 --- src/RESTAPI/RESTAPI_openroaming_gr_cert_handler.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/RESTAPI/RESTAPI_openroaming_gr_cert_handler.cpp b/src/RESTAPI/RESTAPI_openroaming_gr_cert_handler.cpp index 2f39cb8..a122dae 100644 --- a/src/RESTAPI/RESTAPI_openroaming_gr_cert_handler.cpp +++ b/src/RESTAPI/RESTAPI_openroaming_gr_cert_handler.cpp @@ -68,6 +68,8 @@ namespace OpenWifi { if(OpenRoaming_GlobalReach()->CreateRADSECCertificate(AccountInfo.GlobalReachAcctId,NewObject.name,AccountInfo.CSR, NewObject)) { NewObject.id = MicroServiceCreateUUID(); NewObject.accountId = Account; + NewObject.created = Utils::Now(); + NewObject.csr = AccountInfo.CSR; DB_.CreateRecord(NewObject); ProvObjects::GLBLRCertificateInfo CreatedObject; DB_.GetRecord("id",NewObject.id,CreatedObject); From 94ce329143c1a4b23c0e076fe3440fe9171f5b72 Mon Sep 17 00:00:00 2001 From: stephb9959 Date: Tue, 12 Sep 2023 23:17:59 -0700 Subject: [PATCH 22/46] https://telecominfraproject.atlassian.net/browse/WIFI-7831 Signed-off-by: stephb9959 --- src/OpenRoamin_GlobalReach.cpp | 7 ------- 1 file changed, 7 deletions(-) diff --git a/src/OpenRoamin_GlobalReach.cpp b/src/OpenRoamin_GlobalReach.cpp index c7ec0ce..eab6a10 100644 --- a/src/OpenRoamin_GlobalReach.cpp +++ b/src/OpenRoamin_GlobalReach.cpp @@ -84,10 +84,8 @@ namespace OpenWifi { std::ostringstream oos; auto Result = P.parse(is).extract(); Result->stringify(oos); - std::cout << oos.str() << std::endl; } catch( const Poco::Exception &E) { poco_error(Logger(),fmt::format("Could not create a new RADSEC certificate: {},{}",E.name(),E.displayText())); - std::cout << E.name() << " : " << E.displayText() << std::endl; } return false; } @@ -96,7 +94,6 @@ namespace OpenWifi { const std::string &GlobalReachAccountId, std::string &CertificateId, ProvObjects::GLBLRCertificateInfo &NewCertificate) { - std::cout << __LINE__ << ":" << GlobalReachAccountId << std::endl; try { Poco::URI URI{fmt::format("https://config.openro.am/v1/radsec/cert/{}", CertificateId)}; @@ -123,9 +120,6 @@ namespace OpenWifi { RESTAPIHandler::AssignIfPresent(Result,"certificate_chain",NewCertificate.certificateChain); RESTAPIHandler::AssignIfPresent(Result,"certificate_id",NewCertificate.certificateId); RESTAPIHandler::AssignIfPresent(Result,"expires_at",NewCertificate.expiresAt); - std::cout << Response.getStatus() << " : "; - Result->stringify(std::cout); - std::cout << std::endl; return true; } } catch( const Poco::Exception &E) { @@ -140,7 +134,6 @@ namespace OpenWifi { token.setType("JWT"); token.setAlgorithm("ES256"); token.setIssuedAt(std::time(nullptr)); - std::cout << __LINE__ << ":" << GlobalReachAccountId << " : " << PrivateKeys_.size() << std::endl; token.payload().set("iss", GlobalReachAccountId); token.payload().set("iat", (unsigned long) std::time(nullptr)); From 7d995e7cb1a6aaa2b04688f1bcabb67897337338 Mon Sep 17 00:00:00 2001 From: stephb9959 Date: Wed, 13 Sep 2023 10:12:44 -0700 Subject: [PATCH 23/46] https://telecominfraproject.atlassian.net/browse/WIFI-7831 Signed-off-by: stephb9959 --- src/Kafka_ProvUpdater.h | 4 +--- src/framework/EventBusManager.cpp | 6 +++--- src/framework/KafkaManager.cpp | 25 +++++++++++++++++-------- src/framework/KafkaManager.h | 21 ++++++++++++--------- src/framework/ow_constants.h | 14 ++++++++++---- 5 files changed, 43 insertions(+), 27 deletions(-) diff --git a/src/Kafka_ProvUpdater.h b/src/Kafka_ProvUpdater.h index ea26bd3..5a4204d 100644 --- a/src/Kafka_ProvUpdater.h +++ b/src/Kafka_ProvUpdater.h @@ -39,9 +39,7 @@ namespace OpenWifi { Poco::JSON::Object Payload; obj.to_json(Payload); Payload.set("ObjectType", OT); - std::ostringstream OS; - Payload.stringify(OS); - KafkaManager()->PostMessage(KafkaTopics::PROVISIONING_CHANGE, Ops[op], std::make_shared(OS.str())); + KafkaManager()->PostMessage(KafkaTopics::PROVISIONING_CHANGE, Ops[op], Payload); return true; } diff --git a/src/framework/EventBusManager.cpp b/src/framework/EventBusManager.cpp index 28d8037..ca28ad9 100644 --- a/src/framework/EventBusManager.cpp +++ b/src/framework/EventBusManager.cpp @@ -14,18 +14,18 @@ namespace OpenWifi { void EventBusManager::run() { Running_ = true; Utils::SetThreadName("fmwk:EventMgr"); - auto Msg = std::make_shared(MicroServiceMakeSystemEventMessage(KafkaTopics::ServiceEvents::EVENT_JOIN)); + auto Msg = (MicroServiceMakeSystemEventMessage(KafkaTopics::ServiceEvents::EVENT_JOIN)); KafkaManager()->PostMessage(KafkaTopics::SERVICE_EVENTS, MicroServicePrivateEndPoint(), Msg, false); while (Running_) { Poco::Thread::trySleep((unsigned long)MicroServiceDaemonBusTimer()); if (!Running_) break; - Msg = std::make_shared(MicroServiceMakeSystemEventMessage(KafkaTopics::ServiceEvents::EVENT_KEEP_ALIVE)); + Msg = (MicroServiceMakeSystemEventMessage(KafkaTopics::ServiceEvents::EVENT_KEEP_ALIVE)); KafkaManager()->PostMessage(KafkaTopics::SERVICE_EVENTS, MicroServicePrivateEndPoint(), Msg, false); } - Msg = std::make_shared(MicroServiceMakeSystemEventMessage(KafkaTopics::ServiceEvents::EVENT_LEAVE)); + Msg = (MicroServiceMakeSystemEventMessage(KafkaTopics::ServiceEvents::EVENT_LEAVE)); KafkaManager()->PostMessage(KafkaTopics::SERVICE_EVENTS, MicroServicePrivateEndPoint(), Msg, false); }; diff --git a/src/framework/KafkaManager.cpp b/src/framework/KafkaManager.cpp index 09527a5..d32833e 100644 --- a/src/framework/KafkaManager.cpp +++ b/src/framework/KafkaManager.cpp @@ -180,7 +180,7 @@ namespace OpenWifi { Consumer.async_commit(Msg); continue; } - KafkaManager()->Dispatch(Msg.get_topic().c_str(), Msg.get_key(), std::make_shared(Msg.get_payload())); + KafkaManager()->Dispatch(Msg.get_topic().c_str(), Msg.get_key(), Msg.get_payload()); if (!AutoCommit) Consumer.async_commit(Msg); } @@ -213,7 +213,7 @@ namespace OpenWifi { } void KafkaProducer::Produce(const char *Topic, const std::string &Key, - std::shared_ptr Payload) { + const std::string &Payload) { std::lock_guard G(Mutex_); Queue_.enqueueNotification(new KafkaMessage(Topic, Key, Payload)); } @@ -276,7 +276,7 @@ namespace OpenWifi { } void KafkaDispatcher::Dispatch(const char *Topic, const std::string &Key, - const std::shared_ptr Payload) { + const std::string & Payload) { std::lock_guard G(Mutex_); auto It = Notifiers_.find(Topic); if (It != Notifiers_.end()) { @@ -333,20 +333,29 @@ namespace OpenWifi { } void KafkaManager::PostMessage(const char *topic, const std::string &key, - const std::shared_ptr PayLoad, bool WrapMessage) { + const std::string & PayLoad, bool WrapMessage) { if (KafkaEnabled_) { ProducerThr_.Produce(topic, key, WrapMessage ? WrapSystemId(PayLoad) : PayLoad); } } + void KafkaManager::PostMessage(const char *topic, const std::string &key, + const Poco::JSON::Object &Object, bool WrapMessage) { + if (KafkaEnabled_) { + std::ostringstream ObjectStr; + Object.stringify(ObjectStr); + ProducerThr_.Produce(topic, key, WrapMessage ? WrapSystemId(ObjectStr.str()) : ObjectStr.str()); + } + } + + void KafkaManager::Dispatch(const char *Topic, const std::string &Key, - const std::shared_ptr Payload) { + const std::string &Payload) { Dispatcher_.Dispatch(Topic, Key, Payload); } - [[nodiscard]] const std::shared_ptr KafkaManager::WrapSystemId(const std::shared_ptr PayLoad) { - *PayLoad = SystemInfoWrapper_ + *PayLoad + "}"; - return PayLoad; + [[nodiscard]] std::string KafkaManager::WrapSystemId(const std::string & PayLoad) { + return SystemInfoWrapper_ + PayLoad + "}"; } uint64_t KafkaManager::RegisterTopicWatcher(const std::string &Topic, diff --git a/src/framework/KafkaManager.h b/src/framework/KafkaManager.h index 3ef5940..31cf093 100644 --- a/src/framework/KafkaManager.h +++ b/src/framework/KafkaManager.h @@ -6,7 +6,7 @@ #include "Poco/Notification.h" #include "Poco/NotificationQueue.h" - +#include "Poco/JSON/Object.h" #include "framework/KafkaTopics.h" #include "framework/OpenWifiTypes.h" #include "framework/SubSystemServer.h" @@ -18,17 +18,17 @@ namespace OpenWifi { class KafkaMessage : public Poco::Notification { public: - KafkaMessage(const char * Topic, const std::string &Key, std::shared_ptr Payload) + KafkaMessage(const char * Topic, const std::string &Key, const std::string &Payload) : Topic_(Topic), Key_(Key), Payload_(Payload) {} inline const char * Topic() { return Topic_; } inline const std::string &Key() { return Key_; } - inline const std::string &Payload() { return *Payload_; } + inline const std::string &Payload() { return Payload_; } private: const char *Topic_; std::string Key_; - std::shared_ptr Payload_; + std::string Payload_; }; class KafkaProducer : public Poco::Runnable { @@ -36,7 +36,7 @@ namespace OpenWifi { void run() override; void Start(); void Stop(); - void Produce(const char *Topic, const std::string &Key, std::shared_ptr Payload); + void Produce(const char *Topic, const std::string &Key, const std::string & Payload); private: std::recursive_mutex Mutex_; @@ -63,7 +63,7 @@ namespace OpenWifi { void Stop(); auto RegisterTopicWatcher(const std::string &Topic, Types::TopicNotifyFunction &F); void UnregisterTopicWatcher(const std::string &Topic, int Id); - void Dispatch(const char *Topic, const std::string &Key, const std::shared_ptr Payload); + void Dispatch(const char *Topic, const std::string &Key, const std::string & Payload); void run() override; void Topics(std::vector &T); @@ -92,9 +92,12 @@ namespace OpenWifi { void Stop() override; void PostMessage(const char *topic, const std::string &key, - std::shared_ptr PayLoad, bool WrapMessage = true); - void Dispatch(const char *Topic, const std::string &Key, std::shared_ptr Payload); - [[nodiscard]] const std::shared_ptr WrapSystemId(std::shared_ptr PayLoad); + const std::string &PayLoad, bool WrapMessage = true); + void PostMessage(const char *topic, const std::string &key, + const Poco::JSON::Object &Object, bool WrapMessage = true); + + void Dispatch(const char *Topic, const std::string &Key, const std::string &Payload); + [[nodiscard]] std::string WrapSystemId(const std::string & PayLoad); [[nodiscard]] inline bool Enabled() const { return KafkaEnabled_; } uint64_t RegisterTopicWatcher(const std::string &Topic, Types::TopicNotifyFunction &F); void UnregisterTopicWatcher(const std::string &Topic, uint64_t Id); diff --git a/src/framework/ow_constants.h b/src/framework/ow_constants.h index eba39c2..65ed7a3 100644 --- a/src/framework/ow_constants.h +++ b/src/framework/ow_constants.h @@ -406,10 +406,16 @@ namespace OpenWifi::RESTAPI::Errors { 1172, "The venue name already exists." }; - static const struct msg DefFirmwareNameExists { 1172, "Firmware name already exists." }; - static const struct msg NotAValidECKey { 1173, "Provided key supplied is not valid." }; - static const struct msg InvalidGlobalReachAccount { 1174, "Invalid Global Reach account information (id or key)." }; - static const struct msg CannotCreateCSR { 1175, "Could not create CSR" }; + static const struct msg InvalidGlobalReachAccount { + 1173, "Invalid Global Reach account information." + }; + static const struct msg CannotCreateCSR { + 1174, "Cannot create a CSR certificate." + }; + + static const struct msg DefFirmwareNameExists { 1175, "Firmware name already exists." }; + + static const struct msg NotAValidECKey { 1176, "Not a valid Signing Key." }; static const struct msg SimulationDoesNotExist { 7000, "Simulation Instance ID does not exist." From 7b524aa97499709084a02933dab7ccdfa53f62f3 Mon Sep 17 00:00:00 2001 From: stephb9959 Date: Wed, 13 Sep 2023 10:49:18 -0700 Subject: [PATCH 24/46] https://telecominfraproject.atlassian.net/browse/WIFI-7831 Signed-off-by: stephb9959 --- src/RESTAPI/RESTAPI_openroaming_gr_list_certificates.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/RESTAPI/RESTAPI_openroaming_gr_list_certificates.cpp b/src/RESTAPI/RESTAPI_openroaming_gr_list_certificates.cpp index 1f102fe..0bd44f1 100644 --- a/src/RESTAPI/RESTAPI_openroaming_gr_list_certificates.cpp +++ b/src/RESTAPI/RESTAPI_openroaming_gr_list_certificates.cpp @@ -8,7 +8,7 @@ namespace OpenWifi { void RESTAPI_openroaming_gr_list_certificates::DoGet() { - auto Account = GetParameter("account",""); + auto Account = GetBinding("account",""); if(Account.empty()) { return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters); } From 63f49db54c6ee2ba83614075c1f07039de0dffd4 Mon Sep 17 00:00:00 2001 From: stephb9959 Date: Wed, 13 Sep 2023 11:04:43 -0700 Subject: [PATCH 25/46] https://telecominfraproject.atlassian.net/browse/WIFI-7831 Signed-off-by: stephb9959 --- src/framework/SubSystemServer.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/framework/SubSystemServer.cpp b/src/framework/SubSystemServer.cpp index f6df356..47beff9 100644 --- a/src/framework/SubSystemServer.cpp +++ b/src/framework/SubSystemServer.cpp @@ -320,6 +320,8 @@ namespace OpenWifi { } else if (L == "once") M = Poco::Net::Context::VERIFY_ONCE; + std::cout << "Security level: " << level << " : " << L << " : " << M << std::endl; + PropertiesFileServerEntry entry( MicroServiceConfigGetString(address, ""), MicroServiceConfigGetInt(port, 0), MicroServiceConfigPath(key, ""), MicroServiceConfigPath(cert, ""), From 96cfaf5051b503ff4475896549ad05a3d9a37691 Mon Sep 17 00:00:00 2001 From: stephb9959 Date: Wed, 13 Sep 2023 12:11:37 -0700 Subject: [PATCH 26/46] https://telecominfraproject.atlassian.net/browse/WIFI-7831 Signed-off-by: stephb9959 --- src/framework/SubSystemServer.cpp | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/framework/SubSystemServer.cpp b/src/framework/SubSystemServer.cpp index 47beff9..db4dc14 100644 --- a/src/framework/SubSystemServer.cpp +++ b/src/framework/SubSystemServer.cpp @@ -53,7 +53,6 @@ namespace OpenWifi { Context->useCertificate(Cert); Context->addChainCertificate(Root); - Context->addCertificateAuthority(Root); if (level_ == Poco::Net::Context::VERIFY_STRICT) { @@ -76,8 +75,7 @@ namespace OpenWifi { L.fatal(fmt::format("Wrong Certificate({}) for Key({})", cert_file_, key_file_)); } - SSL_CTX_set_verify(SSLCtx, SSL_VERIFY_PEER, nullptr); - + SSL_CTX_set_verify(SSLCtx, SSL_VERIFY_PEER, nullptr); if (level_ == Poco::Net::Context::VERIFY_STRICT) { SSL_CTX_set_client_CA_list(SSLCtx, SSL_load_client_CA_file(client_cas_.c_str())); } @@ -87,7 +85,7 @@ namespace OpenWifi { Context->enableSessionCache(); Context->setSessionCacheSize(0); Context->setSessionTimeout(60); - Context->enableExtendedCertificateVerification(true); + Context->enableExtendedCertificateVerification( level_!= Poco::Net::Context::VERIFY_NONE ); Context->disableStatelessSessionResumption(); } @@ -320,8 +318,6 @@ namespace OpenWifi { } else if (L == "once") M = Poco::Net::Context::VERIFY_ONCE; - std::cout << "Security level: " << level << " : " << L << " : " << M << std::endl; - PropertiesFileServerEntry entry( MicroServiceConfigGetString(address, ""), MicroServiceConfigGetInt(port, 0), MicroServiceConfigPath(key, ""), MicroServiceConfigPath(cert, ""), From 2065bd872d106ca4d271530898dc652ebac1bc95 Mon Sep 17 00:00:00 2001 From: stephb9959 Date: Wed, 13 Sep 2023 13:09:37 -0700 Subject: [PATCH 27/46] https://telecominfraproject.atlassian.net/browse/WIFI-7831 Signed-off-by: stephb9959 --- src/framework/SubSystemServer.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/framework/SubSystemServer.cpp b/src/framework/SubSystemServer.cpp index db4dc14..906e412 100644 --- a/src/framework/SubSystemServer.cpp +++ b/src/framework/SubSystemServer.cpp @@ -37,6 +37,7 @@ namespace OpenWifi { P.cipherList = "ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH"; P.dhUse2048Bits = true; P.caLocation = cas_; + // P.securityLevel = auto Context = Poco::AutoPtr( new Poco::Net::Context(Poco::Net::Context::TLS_SERVER_USE, P)); @@ -75,7 +76,8 @@ namespace OpenWifi { L.fatal(fmt::format("Wrong Certificate({}) for Key({})", cert_file_, key_file_)); } - SSL_CTX_set_verify(SSLCtx, SSL_VERIFY_PEER, nullptr); + SSL_CTX_set_verify(SSLCtx, level_==Poco::Net::Context::VERIFY_NONE ? SSL_VERIFY_NONE : SSL_VERIFY_PEER, nullptr); + if (level_ == Poco::Net::Context::VERIFY_STRICT) { SSL_CTX_set_client_CA_list(SSLCtx, SSL_load_client_CA_file(client_cas_.c_str())); } From 98f37d47483d92efd7a662b9fa4fb16efa977cf3 Mon Sep 17 00:00:00 2001 From: stephb9959 Date: Wed, 13 Sep 2023 13:11:18 -0700 Subject: [PATCH 28/46] https://telecominfraproject.atlassian.net/browse/WIFI-7831 Signed-off-by: stephb9959 --- src/framework/SubSystemServer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/framework/SubSystemServer.cpp b/src/framework/SubSystemServer.cpp index 906e412..9dda8a3 100644 --- a/src/framework/SubSystemServer.cpp +++ b/src/framework/SubSystemServer.cpp @@ -80,8 +80,8 @@ namespace OpenWifi { if (level_ == Poco::Net::Context::VERIFY_STRICT) { SSL_CTX_set_client_CA_list(SSLCtx, SSL_load_client_CA_file(client_cas_.c_str())); + SSL_CTX_enable_ct(SSLCtx, SSL_CT_VALIDATION_STRICT); } - SSL_CTX_enable_ct(SSLCtx, SSL_CT_VALIDATION_STRICT); SSL_CTX_dane_enable(SSLCtx); Context->enableSessionCache(); From 5650e0deccd6a3a13e2a9f6b9ad4c89ee9384fda Mon Sep 17 00:00:00 2001 From: stephb9959 Date: Fri, 15 Sep 2023 15:48:07 -0700 Subject: [PATCH 29/46] https://telecominfraproject.atlassian.net/browse/WIFI-7831 Signed-off-by: stephb9959 --- CMakeLists.txt | 2 +- build | 2 +- openapi/openroaming_globalreach.yaml | 4 +- openapi/openroaming_orion.yaml | 195 ++++++++++++++++++ ...RESTAPI_openroaming_orion_acct_handler.cpp | 8 + .../RESTAPI_openroaming_orion_acct_handler.h | 16 ++ ...PI_openroaming_orion_list_acct_handler.cpp | 8 + ...TAPI_openroaming_orion_list_acct_handler.h | 16 ++ src/RESTObjects/RESTAPI_ProvObjects.cpp | 21 ++ src/RESTObjects/RESTAPI_ProvObjects.h | 10 + 10 files changed, 278 insertions(+), 4 deletions(-) create mode 100644 openapi/openroaming_orion.yaml create mode 100644 src/RESTAPI/RESTAPI_openroaming_orion_acct_handler.cpp create mode 100644 src/RESTAPI/RESTAPI_openroaming_orion_acct_handler.h create mode 100644 src/RESTAPI/RESTAPI_openroaming_orion_list_acct_handler.cpp create mode 100644 src/RESTAPI/RESTAPI_openroaming_orion_list_acct_handler.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 1b813be..ec1cc74 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -209,7 +209,7 @@ add_executable(owprov src/ProvWebSocketClient.cpp src/ProvWebSocketClient.h src/Tasks/VenueRebooter.h src/Tasks/VenueUpgrade.h src/sdks/SDK_fms.cpp src/sdks/SDK_fms.h - src/RESTAPI/RESTAPI_overrides_handler.cpp src/RESTAPI/RESTAPI_overrides_handler.h src/OpenRoamin_GlobalReach.cpp src/OpenRoamin_GlobalReach.h src/storage/storage_glblraccounts.cpp src/storage/storage_glblraccounts.h src/storage/storage_glblrcerts.cpp src/storage/storage_glblrcerts.h src/RESTAPI/RESTAPI_openroaming_gr_list_acct_handler.cpp src/RESTAPI/RESTAPI_openroaming_gr_list_acct_handler.h src/RESTAPI/RESTAPI_openroaming_gr_acct_handler.cpp src/RESTAPI/RESTAPI_openroaming_gr_acct_handler.h src/RESTAPI/RESTAPI_openroaming_gr_list_certificates.cpp src/RESTAPI/RESTAPI_openroaming_gr_list_certificates.h src/RESTAPI/RESTAPI_openroaming_gr_cert_handler.cpp src/RESTAPI/RESTAPI_openroaming_gr_cert_handler.h) + src/RESTAPI/RESTAPI_overrides_handler.cpp src/RESTAPI/RESTAPI_overrides_handler.h src/OpenRoamin_GlobalReach.cpp src/OpenRoamin_GlobalReach.h src/storage/storage_glblraccounts.cpp src/storage/storage_glblraccounts.h src/storage/storage_glblrcerts.cpp src/storage/storage_glblrcerts.h src/RESTAPI/RESTAPI_openroaming_gr_list_acct_handler.cpp src/RESTAPI/RESTAPI_openroaming_gr_list_acct_handler.h src/RESTAPI/RESTAPI_openroaming_gr_acct_handler.cpp src/RESTAPI/RESTAPI_openroaming_gr_acct_handler.h src/RESTAPI/RESTAPI_openroaming_gr_list_certificates.cpp src/RESTAPI/RESTAPI_openroaming_gr_list_certificates.h src/RESTAPI/RESTAPI_openroaming_gr_cert_handler.cpp src/RESTAPI/RESTAPI_openroaming_gr_cert_handler.h src/RESTAPI/RESTAPI_openroaming_orion_list_acct_handler.cpp src/RESTAPI/RESTAPI_openroaming_orion_list_acct_handler.h src/RESTAPI/RESTAPI_openroaming_orion_acct_handler.cpp src/RESTAPI/RESTAPI_openroaming_orion_acct_handler.h) target_link_libraries(owprov PUBLIC ${Poco_LIBRARIES} diff --git a/build b/build index 2edeafb..cabf43b 100644 --- a/build +++ b/build @@ -1 +1 @@ -20 \ No newline at end of file +24 \ No newline at end of file diff --git a/openapi/openroaming_globalreach.yaml b/openapi/openroaming_globalreach.yaml index 8627d56..2a91951 100644 --- a/openapi/openroaming_globalreach.yaml +++ b/openapi/openroaming_globalreach.yaml @@ -1,7 +1,7 @@ openapi: 3.0.1 info: - title: OpenWiFi Provisioning Model - description: Definitions and APIs to manages an OpenWiFi network. + title: OpenWiFi OpenRoaming Provisioning Model for Global Reach + description: Definitions and APIs to Open Roaming WiFi. version: 2.5.0 license: name: BSD3 diff --git a/openapi/openroaming_orion.yaml b/openapi/openroaming_orion.yaml new file mode 100644 index 0000000..847bf7e --- /dev/null +++ b/openapi/openroaming_orion.yaml @@ -0,0 +1,195 @@ +openapi: 3.0.1 +info: + title: OpenWiFi OpenRoaming Provisioning Model for Google Orion + description: Definitions and APIs to Open Roaming WiFi. + version: 2.5.0 + license: + name: BSD3 + url: https://github.com/Telecominfraproject/wlan-cloud-ucentralgw/blob/master/LICENSE + +servers: + - url: 'https://localhost:16005/api/v1' + +security: + - bearerAuth: [] + - ApiKeyAuth: [] + +components: + securitySchemes: + ApiKeyAuth: + type: apiKey + in: header + name: X-API-KEY + bearerAuth: + type: http + scheme: bearer + bearerFormat: JWT + + responses: + NotFound: + $ref: 'https://github.com/Telecominfraproject/wlan-cloud-ucentralsec/blob/main/openpapi/owsec.yaml#/components/responses/NotFound' + Unauthorized: + $ref: 'https://github.com/Telecominfraproject/wlan-cloud-ucentralsec/blob/main/openpapi/owsec.yaml#/components/responses/Unauthorized' + Success: + $ref: 'https://github.com/Telecominfraproject/wlan-cloud-ucentralsec/blob/main/openpapi/owsec.yaml#/components/responses/Success' + BadRequest: + $ref: 'https://github.com/Telecominfraproject/wlan-cloud-ucentralsec/blob/main/openpapi/owsec.yaml#/components/responses/BadRequest' + + schemas: + GooglOrionAccountInfo: + type: object + properties: + allOf: + $ref: 'https://github.com/Telecominfraproject/wlan-cloud-owprov/blob/main/openpapi/owprov.yaml#/components/schemas/ObjectInfo' + privateKey: + type: string + certificate: + type: string + cacerts: + type: array + items: + type: string + +paths: + /openroaming/orion/accounts: + get: + tags: + - OpenRoaming-Google Orion + operationId: getOpenRoamingGlobalReachAccountList + summary: Retrieve account list. + parameters: + - in: query + description: Pagination start (starts at 1. If not specified, 1 is assumed) + name: offset + schema: + type: integer + required: false + - in: query + description: Maximum number of entries to return (if absent, no limit is assumed) + name: limit + schema: + type: integer + required: false + - in: query + description: return the number of accounts + name: countOnly + schema: + type: boolean + required: false + + responses: + 200: + description: The list of accounts + content: + application/json: + schema: + type: array + items: + $ref: '#/components/schemas/GooglOrionAccountInfo' + $ref: '#/components/responses/Success' + 400: + $ref: '#/components/responses/BadRequest' + 403: + $ref: '#/components/responses/Unauthorized' + 404: + $ref: '#/components/responses/NotFound' + + /openroaming/globalreach/account/{name}: + get: + tags: + - OpenRoaming-Google Orion + operationId: getOpenRoamingGlobalReachAccount + summary: Retrieve account information. + parameters: + - in: path + description: The account name + name: name + schema: + type: string + required: true + responses: + 200: + $ref: '#/components/schemas/GooglOrionAccountInfo' + 400: + $ref: '#/components/responses/BadRequest' + 403: + $ref: '#/components/responses/Unauthorized' + 404: + $ref: '#/components/responses/NotFound' + + delete: + tags: + - OpenRoaming-Google Orion + operationId: deleteOpenRoamingGlobalReachAccount + summary: Delete account information. + parameters: + - in: path + description: The account name + name: name + schema: + type: string + required: true + responses: + 200: + $ref: '#/components/responses/Success' + 400: + $ref: '#/components/responses/BadRequest' + 403: + $ref: '#/components/responses/Unauthorized' + 404: + $ref: '#/components/responses/NotFound' + + post: + tags: + - OpenRoaming-Google Orion + operationId: createOpenRoamingGlobalReachAccount + summary: Create account information. + parameters: + - in: path + description: The account name + name: name + schema: + type: string + required: true + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/GooglOrionAccountInfo' + responses: + 200: + $ref: '#/components/schemas/GooglOrionAccountInfo' + 400: + $ref: '#/components/responses/BadRequest' + 403: + $ref: '#/components/responses/Unauthorized' + 404: + $ref: '#/components/responses/NotFound' + + put: + tags: + - OpenRoaming-Google Orion + operationId: modifyOpenRoamingGlobalReachAccount + summary: Modify account information. + parameters: + - in: path + description: The account name + name: name + schema: + type: string + required: true + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/GooglOrionAccountInfo' + responses: + 200: + $ref: '#/components/schemas/GooglOrionAccountInfo' + 400: + $ref: '#/components/responses/BadRequest' + 403: + $ref: '#/components/responses/Unauthorized' + 404: + $ref: '#/components/responses/NotFound' + diff --git a/src/RESTAPI/RESTAPI_openroaming_orion_acct_handler.cpp b/src/RESTAPI/RESTAPI_openroaming_orion_acct_handler.cpp new file mode 100644 index 0000000..7150e06 --- /dev/null +++ b/src/RESTAPI/RESTAPI_openroaming_orion_acct_handler.cpp @@ -0,0 +1,8 @@ +// +// Created by stephane bourque on 2023-09-15. +// + +#include "RESTAPI_openroaming_orion_acct_handler.h" + +namespace OpenWifi { +} // OpenWifi \ No newline at end of file diff --git a/src/RESTAPI/RESTAPI_openroaming_orion_acct_handler.h b/src/RESTAPI/RESTAPI_openroaming_orion_acct_handler.h new file mode 100644 index 0000000..ebdb31d --- /dev/null +++ b/src/RESTAPI/RESTAPI_openroaming_orion_acct_handler.h @@ -0,0 +1,16 @@ +// +// Created by stephane bourque on 2023-09-15. +// + +#ifndef OWPROV_RESTAPI_OPENROAMING_ORION_ACCT_HANDLER_H +#define OWPROV_RESTAPI_OPENROAMING_ORION_ACCT_HANDLER_H + +namespace OpenWifi { + + class RESTAPI_openroaming_orion_acct_handler { + + }; + +} // OpenWifi + +#endif //OWPROV_RESTAPI_OPENROAMING_ORION_ACCT_HANDLER_H diff --git a/src/RESTAPI/RESTAPI_openroaming_orion_list_acct_handler.cpp b/src/RESTAPI/RESTAPI_openroaming_orion_list_acct_handler.cpp new file mode 100644 index 0000000..e15682d --- /dev/null +++ b/src/RESTAPI/RESTAPI_openroaming_orion_list_acct_handler.cpp @@ -0,0 +1,8 @@ +// +// Created by stephane bourque on 2023-09-15. +// + +#include "RESTAPI_openroaming_orion_list_acct_handler.h" + +namespace OpenWifi { +} // OpenWifi \ No newline at end of file diff --git a/src/RESTAPI/RESTAPI_openroaming_orion_list_acct_handler.h b/src/RESTAPI/RESTAPI_openroaming_orion_list_acct_handler.h new file mode 100644 index 0000000..99b7f5c --- /dev/null +++ b/src/RESTAPI/RESTAPI_openroaming_orion_list_acct_handler.h @@ -0,0 +1,16 @@ +// +// Created by stephane bourque on 2023-09-15. +// + +#ifndef OWPROV_RESTAPI_OPENROAMING_ORION_LIST_ACCT_HANDLER_H +#define OWPROV_RESTAPI_OPENROAMING_ORION_LIST_ACCT_HANDLER_H + +namespace OpenWifi { + + class RESTAPI_openroaming_orion_list_acct_handler { + + }; + +} // OpenWifi + +#endif //OWPROV_RESTAPI_OPENROAMING_ORION_LIST_ACCT_HANDLER_H diff --git a/src/RESTObjects/RESTAPI_ProvObjects.cpp b/src/RESTObjects/RESTAPI_ProvObjects.cpp index cf88234..c2166eb 100644 --- a/src/RESTObjects/RESTAPI_ProvObjects.cpp +++ b/src/RESTObjects/RESTAPI_ProvObjects.cpp @@ -1258,4 +1258,25 @@ namespace OpenWifi::ProvObjects { return false; } + void GooglOrionAccountInfo::to_json(Poco::JSON::Object &Obj) const { + info.to_json(Obj); + field_to_json(Obj, "privateKey", privateKey); + field_to_json(Obj, "certificate", certificate); + field_to_json(Obj, "cacerts", cacerts); + } + + bool GooglOrionAccountInfo::from_json(const Poco::JSON::Object::Ptr &Obj) { + try { + info.from_json(Obj); + field_from_json(Obj, "privateKey", privateKey); + field_from_json(Obj, "certificate", certificate); + field_from_json(Obj, "cacerts", cacerts); + return true; + } catch (const Poco::Exception &E) { + + } + return false; + } + + } // namespace OpenWifi::ProvObjects diff --git a/src/RESTObjects/RESTAPI_ProvObjects.h b/src/RESTObjects/RESTAPI_ProvObjects.h index ec8f449..725b9cc 100644 --- a/src/RESTObjects/RESTAPI_ProvObjects.h +++ b/src/RESTObjects/RESTAPI_ProvObjects.h @@ -773,4 +773,14 @@ namespace OpenWifi::ProvObjects { bool from_json(const Poco::JSON::Object::Ptr &Obj); }; + struct GooglOrionAccountInfo { + ObjectInfo info; + std::string privateKey; + std::string certificate; + std::vector cacerts; + + void to_json(Poco::JSON::Object &Obj) const; + bool from_json(const Poco::JSON::Object::Ptr &Obj); + }; + }; // namespace OpenWifi::ProvObjects From f2b1169d8c1145c29928699abe5ade75b35f595c Mon Sep 17 00:00:00 2001 From: stephb9959 Date: Sun, 17 Sep 2023 23:20:45 -0700 Subject: [PATCH 30/46] https://telecominfraproject.atlassian.net/browse/WIFI-7831 Signed-off-by: stephb9959 --- CMakeLists.txt | 2 +- build | 2 +- openapi/openroaming_orion.yaml | 2 +- ...RESTAPI_openroaming_orion_acct_handler.cpp | 92 ++++++++++++++++ .../RESTAPI_openroaming_orion_acct_handler.h | 30 +++-- ...PI_openroaming_orion_list_acct_handler.cpp | 13 +++ ...TAPI_openroaming_orion_list_acct_handler.h | 27 +++-- src/StorageService.cpp | 16 ++- src/StorageService.h | 3 + src/framework/ow_constants.h | 2 + src/framework/utils.cpp | 103 ++++++++++++++++++ src/framework/utils.h | 6 +- src/storage/storage_orion_accounts.cpp | 76 +++++++++++++ src/storage/storage_orion_accounts.h | 32 ++++++ 14 files changed, 382 insertions(+), 24 deletions(-) create mode 100644 src/storage/storage_orion_accounts.cpp create mode 100644 src/storage/storage_orion_accounts.h diff --git a/CMakeLists.txt b/CMakeLists.txt index ec1cc74..983d7d4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -209,7 +209,7 @@ add_executable(owprov src/ProvWebSocketClient.cpp src/ProvWebSocketClient.h src/Tasks/VenueRebooter.h src/Tasks/VenueUpgrade.h src/sdks/SDK_fms.cpp src/sdks/SDK_fms.h - src/RESTAPI/RESTAPI_overrides_handler.cpp src/RESTAPI/RESTAPI_overrides_handler.h src/OpenRoamin_GlobalReach.cpp src/OpenRoamin_GlobalReach.h src/storage/storage_glblraccounts.cpp src/storage/storage_glblraccounts.h src/storage/storage_glblrcerts.cpp src/storage/storage_glblrcerts.h src/RESTAPI/RESTAPI_openroaming_gr_list_acct_handler.cpp src/RESTAPI/RESTAPI_openroaming_gr_list_acct_handler.h src/RESTAPI/RESTAPI_openroaming_gr_acct_handler.cpp src/RESTAPI/RESTAPI_openroaming_gr_acct_handler.h src/RESTAPI/RESTAPI_openroaming_gr_list_certificates.cpp src/RESTAPI/RESTAPI_openroaming_gr_list_certificates.h src/RESTAPI/RESTAPI_openroaming_gr_cert_handler.cpp src/RESTAPI/RESTAPI_openroaming_gr_cert_handler.h src/RESTAPI/RESTAPI_openroaming_orion_list_acct_handler.cpp src/RESTAPI/RESTAPI_openroaming_orion_list_acct_handler.h src/RESTAPI/RESTAPI_openroaming_orion_acct_handler.cpp src/RESTAPI/RESTAPI_openroaming_orion_acct_handler.h) + src/RESTAPI/RESTAPI_overrides_handler.cpp src/RESTAPI/RESTAPI_overrides_handler.h src/OpenRoamin_GlobalReach.cpp src/OpenRoamin_GlobalReach.h src/storage/storage_glblraccounts.cpp src/storage/storage_glblraccounts.h src/storage/storage_glblrcerts.cpp src/storage/storage_glblrcerts.h src/RESTAPI/RESTAPI_openroaming_gr_list_acct_handler.cpp src/RESTAPI/RESTAPI_openroaming_gr_list_acct_handler.h src/RESTAPI/RESTAPI_openroaming_gr_acct_handler.cpp src/RESTAPI/RESTAPI_openroaming_gr_acct_handler.h src/RESTAPI/RESTAPI_openroaming_gr_list_certificates.cpp src/RESTAPI/RESTAPI_openroaming_gr_list_certificates.h src/RESTAPI/RESTAPI_openroaming_gr_cert_handler.cpp src/RESTAPI/RESTAPI_openroaming_gr_cert_handler.h src/RESTAPI/RESTAPI_openroaming_orion_list_acct_handler.cpp src/RESTAPI/RESTAPI_openroaming_orion_list_acct_handler.h src/RESTAPI/RESTAPI_openroaming_orion_acct_handler.cpp src/RESTAPI/RESTAPI_openroaming_orion_acct_handler.h src/storage/storage_orion_accounts.cpp src/storage/storage_orion_accounts.h) target_link_libraries(owprov PUBLIC ${Poco_LIBRARIES} diff --git a/build b/build index cabf43b..d99e90e 100644 --- a/build +++ b/build @@ -1 +1 @@ -24 \ No newline at end of file +29 \ No newline at end of file diff --git a/openapi/openroaming_orion.yaml b/openapi/openroaming_orion.yaml index 847bf7e..d2cb132 100644 --- a/openapi/openroaming_orion.yaml +++ b/openapi/openroaming_orion.yaml @@ -94,7 +94,7 @@ paths: 404: $ref: '#/components/responses/NotFound' - /openroaming/globalreach/account/{name}: + /openroaming/globalreach/account/{id}: get: tags: - OpenRoaming-Google Orion diff --git a/src/RESTAPI/RESTAPI_openroaming_orion_acct_handler.cpp b/src/RESTAPI/RESTAPI_openroaming_orion_acct_handler.cpp index 7150e06..b985f1a 100644 --- a/src/RESTAPI/RESTAPI_openroaming_orion_acct_handler.cpp +++ b/src/RESTAPI/RESTAPI_openroaming_orion_acct_handler.cpp @@ -3,6 +3,98 @@ // #include "RESTAPI_openroaming_orion_acct_handler.h" +#include "OpenRoamin_GlobalReach.h" namespace OpenWifi { + + void RESTAPI_openroaming_orion_acct_handler::DoGet() { + auto Account = GetBinding("id",""); + if(Account.empty()) { + return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters); + } + + ProvObjects::GooglOrionAccountInfo Record; + if(DB_.GetRecord("id",Account,Record)) { + return ReturnObject(Record); + } + return NotFound(); + } + + void RESTAPI_openroaming_orion_acct_handler::DoDelete() { + auto Account = GetBinding("id",""); + if(Account.empty()) { + return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters); + } + + ProvObjects::GooglOrionAccountInfo Record; + if(!DB_.GetRecord("id",Account,Record)) { + return NotFound(); + } + DB_.DeleteRecord("id", Account); + return OK(); + } + + void RESTAPI_openroaming_orion_acct_handler::DoPost() { + auto Account = GetBinding("id",""); + if(Account.empty()) { + return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters); + } + + const auto &RawObject = ParsedBody_; + ProvObjects::GooglOrionAccountInfo NewObject; + if( !NewObject.from_json(RawObject)) { + return BadRequest(OpenWifi::RESTAPI::Errors::InvalidJSONDocument); + } + + if( NewObject.privateKey.empty() || + NewObject.certificate.empty() || + NewObject.cacerts.empty()) { + return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters); + } + + if( !Utils::VerifyRSAKey(NewObject.privateKey) || + !Utils::ValidX509Certificate(NewObject.certificate) || + !Utils::ValidX509Certificate(NewObject.cacerts)) { + return BadRequest(RESTAPI::Errors::NotAValidECKey); + } + + ProvObjects::CreateObjectInfo(RawObject,UserInfo_.userinfo,NewObject.info); + + if(DB_.CreateRecord(NewObject)) { + ProvObjects::GooglOrionAccountInfo StoredObject; + DB_.GetRecord("id",NewObject.info.id,StoredObject); + return ReturnObject(StoredObject); + } + return BadRequest(RESTAPI::Errors::RecordNotCreated); + } + + void RESTAPI_openroaming_orion_acct_handler::DoPut() { + auto Account = GetBinding("account",""); + if(Account.empty()) { + return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters); + } + + const auto &RawObject = ParsedBody_; + ProvObjects::GLBLRAccountInfo Modify; + if(!Modify.from_json(RawObject)) { + return BadRequest(OpenWifi::RESTAPI::Errors::InvalidJSONDocument); + } + + ProvObjects::GooglOrionAccountInfo Existing; + if(!DB_.GetRecord("id",Account,Existing)) { + return NotFound(); + } + + if(!ProvObjects::UpdateObjectInfo(RawObject,UserInfo_.userinfo,Existing.info)) { + return BadRequest(OpenWifi::RESTAPI::Errors::InvalidJSONDocument); + } + + if(DB_.UpdateRecord("id",Existing.info.id,Existing)) { + ProvObjects::GooglOrionAccountInfo StoredObject; + DB_.GetRecord("id",Existing.info.id,StoredObject); + return ReturnObject(StoredObject); + } + return BadRequest(RESTAPI::Errors::RecordNotUpdated); + } + } // OpenWifi \ No newline at end of file diff --git a/src/RESTAPI/RESTAPI_openroaming_orion_acct_handler.h b/src/RESTAPI/RESTAPI_openroaming_orion_acct_handler.h index ebdb31d..a896b2b 100644 --- a/src/RESTAPI/RESTAPI_openroaming_orion_acct_handler.h +++ b/src/RESTAPI/RESTAPI_openroaming_orion_acct_handler.h @@ -2,15 +2,29 @@ // Created by stephane bourque on 2023-09-15. // -#ifndef OWPROV_RESTAPI_OPENROAMING_ORION_ACCT_HANDLER_H -#define OWPROV_RESTAPI_OPENROAMING_ORION_ACCT_HANDLER_H +#pragma once +#include "StorageService.h" +#include "framework/RESTAPI_Handler.h" namespace OpenWifi { + class RESTAPI_openroaming_orion_acct_handler : public RESTAPIHandler { + public: + RESTAPI_openroaming_orion_acct_handler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, + RESTAPI_GenericServerAccounting &Server, uint64_t TransactionId, + bool Internal) + : RESTAPIHandler(bindings, L, + std::vector{Poco::Net::HTTPRequest::HTTP_GET, + Poco::Net::HTTPRequest::HTTP_DELETE, + Poco::Net::HTTPRequest::HTTP_POST, + Poco::Net::HTTPRequest::HTTP_OPTIONS}, + Server, TransactionId, Internal) {} + static auto PathName() { return std::list{"/api/v1/openroaming/orion/account/{id}"}; }; - class RESTAPI_openroaming_orion_acct_handler { - + private: + OrionAccountsDB &DB_ = StorageService()->OrionAccountsDB(); + void DoGet() final; + void DoPost() final; + void DoPut() final; + void DoDelete() final; }; - -} // OpenWifi - -#endif //OWPROV_RESTAPI_OPENROAMING_ORION_ACCT_HANDLER_H +} // namespace OpenWifi diff --git a/src/RESTAPI/RESTAPI_openroaming_orion_list_acct_handler.cpp b/src/RESTAPI/RESTAPI_openroaming_orion_list_acct_handler.cpp index e15682d..3041d33 100644 --- a/src/RESTAPI/RESTAPI_openroaming_orion_list_acct_handler.cpp +++ b/src/RESTAPI/RESTAPI_openroaming_orion_list_acct_handler.cpp @@ -4,5 +4,18 @@ #include "RESTAPI_openroaming_orion_list_acct_handler.h" + namespace OpenWifi { + + void RESTAPI_openroaming_orion_list_acct_handler::DoGet() { + + if(GetBoolParameter("countOnly")) { + return ReturnCountOnly(DB_.Count()); + } + + std::vector Accounts; + DB_.GetRecords(QB_.Offset,QB_.Limit,Accounts); + return ReturnObject(Accounts); + } + } // OpenWifi \ No newline at end of file diff --git a/src/RESTAPI/RESTAPI_openroaming_orion_list_acct_handler.h b/src/RESTAPI/RESTAPI_openroaming_orion_list_acct_handler.h index 99b7f5c..864a69b 100644 --- a/src/RESTAPI/RESTAPI_openroaming_orion_list_acct_handler.h +++ b/src/RESTAPI/RESTAPI_openroaming_orion_list_acct_handler.h @@ -2,15 +2,28 @@ // Created by stephane bourque on 2023-09-15. // -#ifndef OWPROV_RESTAPI_OPENROAMING_ORION_LIST_ACCT_HANDLER_H -#define OWPROV_RESTAPI_OPENROAMING_ORION_LIST_ACCT_HANDLER_H +#pragma once +#include "StorageService.h" +#include "framework/RESTAPI_Handler.h" namespace OpenWifi { + class RESTAPI_openroaming_orion_list_acct_handler : public RESTAPIHandler { + public: + RESTAPI_openroaming_orion_list_acct_handler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, + RESTAPI_GenericServerAccounting &Server, uint64_t TransactionId, + bool Internal) + : RESTAPIHandler(bindings, L, + std::vector{Poco::Net::HTTPRequest::HTTP_GET, + Poco::Net::HTTPRequest::HTTP_OPTIONS}, + Server, TransactionId, Internal) {} + static auto PathName() { return std::list{"/api/v1/openroaming/orion/accounts"}; }; - class RESTAPI_openroaming_orion_list_acct_handler { - + private: + OrionAccountsDB &DB_ = StorageService()->OrionAccountsDB(); + void DoGet() final; + void DoPost() final{}; + void DoPut() final{}; + void DoDelete() final{}; }; +} // namespace OpenWifi -} // OpenWifi - -#endif //OWPROV_RESTAPI_OPENROAMING_ORION_LIST_ACCT_HANDLER_H diff --git a/src/StorageService.cpp b/src/StorageService.cpp index 1a1e193..cfd1b23 100644 --- a/src/StorageService.cpp +++ b/src/StorageService.cpp @@ -41,6 +41,7 @@ namespace OpenWifi { OverridesDB_ = std::make_unique(dbType_, *Pool_, Logger()); GLBLRAccountInfoDB_ = std::make_unique(dbType_, *Pool_, Logger()); GLBLRCertsDB_ = std::make_unique(dbType_, *Pool_, Logger()); + OrionAccountsDB_ = std::make_unique(dbType_, *Pool_, Logger()); EntityDB_->Create(); PolicyDB_->Create(); @@ -63,6 +64,7 @@ namespace OpenWifi { OverridesDB_->Create(); GLBLRAccountInfoDB_->Create(); GLBLRCertsDB_->Create(); + OrionAccountsDB_->Create(); ExistFunc_[EntityDB_->Prefix()] = [=](const char *F, std::string &V) -> bool { return EntityDB_->Exists(F, V); @@ -127,10 +129,13 @@ namespace OpenWifi { ExistFunc_[GLBLRCertsDB_->Prefix()] = [=](const char *F, std::string &V) -> bool { return GLBLRCertsDB_->Exists(F, V); }; + ExistFunc_[GLBLRCertsDB_->Prefix()] = [=](const char *F, std::string &V) -> bool { + return OrionAccountsDB_->Exists(F, V); + }; - ExpandFunc_[EntityDB_->Prefix()] = [=](const char *F, std::string &V, std::string &Name, + ExpandFunc_[EntityDB_->Prefix()] = [=](const char *F, std::string &V, std::string &Name, std::string &Description) -> bool { return EntityDB_->GetNameAndDescription(F, V, Name, Description); }; @@ -218,7 +223,6 @@ namespace OpenWifi { [=]([[maybe_unused]] const char *F, [[maybe_unused]] std::string &V, [[maybe_unused]] std::string &Name, [[maybe_unused]] std::string &Description) -> bool { return false; }; - ExpandFunc_[GLBLRAccountInfoDB_->Prefix()] = [=]([[maybe_unused]] const char *F, [[maybe_unused]] std::string &V, [[maybe_unused]] std::string &Name, @@ -227,14 +231,16 @@ namespace OpenWifi { [=]([[maybe_unused]] const char *F, [[maybe_unused]] std::string &V, [[maybe_unused]] std::string &Name, [[maybe_unused]] std::string &Description) -> bool { return false; }; - ExpandFunc_[GLBLRCertsDB_->Prefix()] = [=]([[maybe_unused]] const char *F, [[maybe_unused]] std::string &V, [[maybe_unused]] std::string &Name, [[maybe_unused]] std::string &Description) -> bool { return false; }; + ExpandFunc_[OrionAccountsDB_->Prefix()] = + [=]([[maybe_unused]] const char *F, [[maybe_unused]] std::string &V, + [[maybe_unused]] std::string &Name, + [[maybe_unused]] std::string &Description) -> bool { return false; }; - InventoryDB_->InitializeSerialCache(); - + InventoryDB_->InitializeSerialCache(); ConsistencyCheck(); InitializeSystemDBs(); diff --git a/src/StorageService.h b/src/StorageService.h index adafaa8..0de189f 100644 --- a/src/StorageService.h +++ b/src/StorageService.h @@ -30,6 +30,7 @@ #include "storage/storage_venue.h" #include "storage/storage_glblraccounts.h" #include "storage/storage_glblrcerts.h" +#include "storage/storage_orion_accounts.h" #include "Poco/URI.h" #include "framework/ow_constants.h" @@ -70,6 +71,7 @@ namespace OpenWifi { inline OpenWifi::OverridesDB &OverridesDB() { return *OverridesDB_; }; inline OpenWifi::GLBLRAccountInfoDB &GLBLRAccountInfoDB() { return *GLBLRAccountInfoDB_; } inline OpenWifi::GLBLRCertsDB &GLBLRCertsDB() { return *GLBLRCertsDB_; } + inline OpenWifi::OrionAccountsDB &OrionAccountsDB() { return *OrionAccountsDB_; } bool Validate(const Poco::URI::QueryParameters &P, RESTAPI::Errors::msg &Error); bool Validate(const Types::StringVec &P, std::string &Error); @@ -131,6 +133,7 @@ namespace OpenWifi { std::unique_ptr OverridesDB_; std::unique_ptr GLBLRAccountInfoDB_; std::unique_ptr GLBLRCertsDB_; + std::unique_ptr OrionAccountsDB_; std::string DefaultOperator_; typedef std::function exist_func; diff --git a/src/framework/ow_constants.h b/src/framework/ow_constants.h index 65ed7a3..370ab40 100644 --- a/src/framework/ow_constants.h +++ b/src/framework/ow_constants.h @@ -417,6 +417,8 @@ namespace OpenWifi::RESTAPI::Errors { static const struct msg NotAValidECKey { 1176, "Not a valid Signing Key." }; + static const struct msg NotAValidRadiusPoolType { 1177, "Not a valid RADIUS pool type." }; + static const struct msg SimulationDoesNotExist { 7000, "Simulation Instance ID does not exist." }; diff --git a/src/framework/utils.cpp b/src/framework/utils.cpp index b4486ba..6c34cdb 100644 --- a/src/framework/utils.cpp +++ b/src/framework/utils.cpp @@ -8,6 +8,12 @@ #include "framework/AppServiceRegistry.h" #include "framework/utils.h" +#include +#include +#include +#include +#include + namespace OpenWifi::Utils { bool NormalizeMac(std::string &Mac) { @@ -759,4 +765,101 @@ namespace OpenWifi::Utils { return false; } + bool VerifyRSAKey([[ + maybe_unused]] const std::string &key) { + try { + Poco::TemporaryFile F; + + std::ofstream of(F.path().c_str(), std::ios_base::trunc | std::ios_base::out | std::ios_base::binary); + of << key; + of.close(); + + auto Key = Poco::SharedPtr( + new Poco::Crypto::RSAKey("", F.path(),"")); + return true; + } catch (const Poco::Exception &E) { + + } + return false; + } + + bool ValidX509Certificate([[ + maybe_unused]] const std::string &Cert) { + try { + Poco::TemporaryFile F; + std::ofstream of(F.path().c_str(), std::ios_base::trunc | std::ios_base::out | std::ios_base::binary); + of << Cert; + of.close(); + + auto Key = Poco::SharedPtr( + new Poco::Crypto::X509Certificate(F.path())); + return true; + } catch (const Poco::Exception &E) { + + } + return false; + } + + bool ValidX509Certificate([[ + maybe_unused]] const std::vector &Certs) { + auto F = [](const std::string &C) -> bool { return ValidX509Certificate(C); }; + return std::all_of(Certs.begin(),Certs.end(), F); + } + + std::string generateStrongPassword(int minLength, int maxLength, int numDigits, int minLowercase, int minSpecial, int minUppercase) { + // Define character sets for each category + const std::string lowercaseChars = "abcdefghijklmnopqrstuvwxyz"; + const std::string uppercaseChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; + const std::string digitChars = "0123456789"; + const std::string specialChars = "!@#$%^&*()_+[]{}|;:,.<>?"; + + // Check if parameters are valid + if (minLength < 1 || minLength > maxLength || minLowercase + minUppercase + numDigits + minSpecial > maxLength) { + return "Invalid parameters"; + } + + // Initialize random seed + std::random_device rd; + std::mt19937 g(rd()); + + // Initialize the password string + std::string password; + + // Generate the required number of each character type + for (int i = 0; i < minLowercase; ++i) { + password += lowercaseChars[g() % lowercaseChars.length()]; + } + for (int i = 0; i < minUppercase; ++i) { + password += uppercaseChars[g() % uppercaseChars.length()]; + } + for (int i = 0; i < numDigits; ++i) { + password += digitChars[g() % digitChars.length()]; + } + for (int i = 0; i < minSpecial; ++i) { + password += specialChars[g() % specialChars.length()]; + } + + // Calculate how many more characters are needed + int remainingLength = maxLength - (int)password.length(); + + // Generate random characters to fill the remaining length + for (int i = 0; i < remainingLength; ++i) { + int category = g() % 4; // Randomly select a category + if (category == 0) { + password += lowercaseChars[g() % lowercaseChars.length()]; + } else if (category == 1) { + password += uppercaseChars[g() % uppercaseChars.length()]; + } else if (category == 2) { + password += digitChars[g() % digitChars.length()]; + } else { + password += specialChars[g() % specialChars.length()]; + } + } + + // Shuffle the password to randomize the character order + std::shuffle(password.begin(), password.end(),g); + + return password; + } + } // namespace OpenWifi::Utils diff --git a/src/framework/utils.h b/src/framework/utils.h index 9a9c939..cf708bd 100644 --- a/src/framework/utils.h +++ b/src/framework/utils.h @@ -258,6 +258,10 @@ namespace OpenWifi::Utils { }; bool CreateX509CSR(const CSRCreationParameters & Parameters, CSRCreationResults & Results); - + std::string generateStrongPassword(int minLength, int maxLength, int numDigits, int minLowercase, int minSpecial, int minUppercase); bool VerifyECKey(const std::string &key); + bool VerifyRSAKey(const std::string &key); + bool ValidX509Certificate(const std::string &Cert); + bool ValidX509Certificate(const std::vector &Certs); + } // namespace OpenWifi::Utils diff --git a/src/storage/storage_orion_accounts.cpp b/src/storage/storage_orion_accounts.cpp new file mode 100644 index 0000000..1f548fb --- /dev/null +++ b/src/storage/storage_orion_accounts.cpp @@ -0,0 +1,76 @@ +// +// Created by stephane bourque on 2023-09-17. +// + +#include "storage_orion_accounts.h" +#include +#include "framework/OpenWifiTypes.h" +#include "framework/RESTAPI_utils.h" + +#include "RESTObjects/RESTAPI_SecurityObjects.h" + +namespace OpenWifi { + + static ORM::FieldVec OrionAccountsDB_Fields{ + ORM::Field{"id", 64, true}, + ORM::Field{"name", ORM::FieldType::FT_TEXT}, + ORM::Field{"description", ORM::FieldType::FT_TEXT}, + ORM::Field{"notes", ORM::FieldType::FT_TEXT}, + ORM::Field{"created", ORM::FieldType::FT_BIGINT}, + ORM::Field{"modified", ORM::FieldType::FT_BIGINT}, + ORM::Field{"privateKey", ORM::FieldType::FT_TEXT}, + ORM::Field{"certificate", ORM::FieldType::FT_TEXT}, + ORM::Field{"cacerts", ORM::FieldType::FT_TEXT} + }; + + static ORM::IndexVec OrionAccountsDB_Indexes{ + {std::string("orion_name_index"), + ORM::IndexEntryVec{{std::string("name"), ORM::Indextype::ASC}}}}; + + OrionAccountsDB::OrionAccountsDB(OpenWifi::DBType T, Poco::Data::SessionPool &P, Poco::Logger &L) + : DB(T, "orion_accts", OrionAccountsDB_Fields, OrionAccountsDB_Indexes, P, L, "oat") {} + + bool OrionAccountsDB::Upgrade([[maybe_unused]] uint32_t from, uint32_t &to) { + to = Version(); + std::vector Script{}; + + for (const auto &i : Script) { + try { + auto Session = Pool_.get(); + Session << i, Poco::Data::Keywords::now; + } catch (...) { + } + } + return true; + } + +} // namespace OpenWifi + +template <> +void ORM::DB::Convert( + const OpenWifi::OrionAccountsDBRecordType &In, OpenWifi::ProvObjects::GooglOrionAccountInfo &Out) { + Out.info.id = In.get<0>(); + Out.info.name = In.get<1>(); + Out.info.description = In.get<2>(); + Out.info.notes = + OpenWifi::RESTAPI_utils::to_object_array(In.get<3>()); + Out.info.created = In.get<4>(); + Out.info.modified = In.get<5>(); + Out.privateKey =In.get<6>(); + Out.certificate = In.get<7>(); + Out.cacerts = OpenWifi::RESTAPI_utils::to_object_array(In.get<8>()); +} + +template <> +void ORM::DB::Convert( + const OpenWifi::ProvObjects::GooglOrionAccountInfo &In, OpenWifi::OrionAccountsDBRecordType &Out) { + Out.set<0>(In.info.id); + Out.set<1>(In.info.name); + Out.set<2>(In.info.description); + Out.set<3>(OpenWifi::RESTAPI_utils::to_string(In.info.notes)); + Out.set<4>(In.info.created); + Out.set<5>(In.info.modified); + Out.set<6>(In.privateKey); + Out.set<7>(In.certificate); + Out.set<8>(OpenWifi::RESTAPI_utils::to_string(In.cacerts)); +} diff --git a/src/storage/storage_orion_accounts.h b/src/storage/storage_orion_accounts.h new file mode 100644 index 0000000..937d15c --- /dev/null +++ b/src/storage/storage_orion_accounts.h @@ -0,0 +1,32 @@ +// +// Created by stephane bourque on 2023-09-17. +// + +#pragma once + +#include "RESTObjects/RESTAPI_ProvObjects.h" +#include "framework/orm.h" + +namespace OpenWifi { + + typedef Poco::Tuple + OrionAccountsDBRecordType; + + class OrionAccountsDB : public ORM::DB { + public: + OrionAccountsDB(OpenWifi::DBType T, Poco::Data::SessionPool &P, Poco::Logger &L); + virtual ~OrionAccountsDB(){}; + bool Upgrade(uint32_t from, uint32_t &to) override; + private: + + }; + +} // namespace OpenWifi From a1176e7f4d010575aa698c00c2d9ac91ce7fa050 Mon Sep 17 00:00:00 2001 From: stephb9959 Date: Sun, 17 Sep 2023 23:34:14 -0700 Subject: [PATCH 31/46] https://telecominfraproject.atlassian.net/browse/WIFI-7831 Signed-off-by: stephb9959 --- src/RESTAPI/RESTAPI_openroaming_orion_acct_handler.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/RESTAPI/RESTAPI_openroaming_orion_acct_handler.cpp b/src/RESTAPI/RESTAPI_openroaming_orion_acct_handler.cpp index b985f1a..be839ad 100644 --- a/src/RESTAPI/RESTAPI_openroaming_orion_acct_handler.cpp +++ b/src/RESTAPI/RESTAPI_openroaming_orion_acct_handler.cpp @@ -52,7 +52,7 @@ namespace OpenWifi { return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters); } - if( !Utils::VerifyRSAKey(NewObject.privateKey) || + if( !Utils::VerifyECKey(NewObject.privateKey) || !Utils::ValidX509Certificate(NewObject.certificate) || !Utils::ValidX509Certificate(NewObject.cacerts)) { return BadRequest(RESTAPI::Errors::NotAValidECKey); From 4c2ba2ec28708f8cb8d54c0e1f4a48fcd959899a Mon Sep 17 00:00:00 2001 From: stephb9959 Date: Mon, 18 Sep 2023 07:12:22 -0700 Subject: [PATCH 32/46] https://telecominfraproject.atlassian.net/browse/WIFI-7831 Signed-off-by: stephb9959 --- src/RESTAPI/RESTAPI_routers.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/RESTAPI/RESTAPI_routers.cpp b/src/RESTAPI/RESTAPI_routers.cpp index 441f2aa..62ba3bb 100644 --- a/src/RESTAPI/RESTAPI_routers.cpp +++ b/src/RESTAPI/RESTAPI_routers.cpp @@ -39,6 +39,8 @@ #include "RESTAPI/RESTAPI_openroaming_gr_list_acct_handler.h" #include "RESTAPI/RESTAPI_openroaming_gr_cert_handler.h" #include "RESTAPI/RESTAPI_openroaming_gr_list_certificates.h" +#include "RESTAPI/RESTAPI_openroaming_orion_acct_handler.h" +#include "RESTAPI/RESTAPI_openroaming_orion_list_acct_handler.h" #include "framework/RESTAPI_SystemCommand.h" #include "framework/RESTAPI_WebSocketServer.h" @@ -66,7 +68,8 @@ namespace OpenWifi { RESTAPI_op_contact_list_handler, RESTAPI_op_location_handler, RESTAPI_op_location_list_handler, RESTAPI_asset_server, RESTAPI_overrides_handler, RESTAPI_openroaming_gr_acct_handler, RESTAPI_openroaming_gr_list_acct_handler, - RESTAPI_openroaming_gr_cert_handler, RESTAPI_openroaming_gr_list_certificates>( + RESTAPI_openroaming_gr_cert_handler, RESTAPI_openroaming_gr_list_certificates, + RESTAPI_openroaming_orion_acct_handler, RESTAPI_openroaming_orion_list_acct_handler>( Path, Bindings, L, S, TransactionId); } @@ -90,7 +93,8 @@ namespace OpenWifi { RESTAPI_op_contact_list_handler, RESTAPI_op_location_handler, RESTAPI_op_location_list_handler, RESTAPI_overrides_handler, RESTAPI_openroaming_gr_acct_handler, RESTAPI_openroaming_gr_list_acct_handler, - RESTAPI_openroaming_gr_cert_handler, RESTAPI_openroaming_gr_list_certificates>(Path, Bindings, L, S, + RESTAPI_openroaming_gr_cert_handler, RESTAPI_openroaming_gr_list_certificates, + RESTAPI_openroaming_orion_acct_handler, RESTAPI_openroaming_orion_list_acct_handler>(Path, Bindings, L, S, TransactionId); } } // namespace OpenWifi \ No newline at end of file From 4c9dbd76e1033ec49c924929b96c93b2ccc3d8f3 Mon Sep 17 00:00:00 2001 From: stephb9959 Date: Mon, 18 Sep 2023 09:36:24 -0700 Subject: [PATCH 33/46] https://telecominfraproject.atlassian.net/browse/WIFI-7831 Signed-off-by: stephb9959 --- src/framework/ConfigurationValidator.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/framework/ConfigurationValidator.cpp b/src/framework/ConfigurationValidator.cpp index f1bb9ef..00de09b 100644 --- a/src/framework/ConfigurationValidator.cpp +++ b/src/framework/ConfigurationValidator.cpp @@ -28,7 +28,6 @@ static const std::string GitUCentralJSONSchemaFile{ "ucentral.schema.json"}; static std::string DefaultUCentralSchema = R"foo( - { "$id": "https://openwrt.org/ucentral.schema.json", "$schema": "http://json-schema.org/draft-07/schema#", @@ -3326,7 +3325,6 @@ static std::string DefaultUCentralSchema = R"foo( } } } - )foo"; static inline bool IsIPv4(const std::string &value) { From 9068eb32b7243f6a412b09bddba31db5942f2d3e Mon Sep 17 00:00:00 2001 From: stephb9959 Date: Mon, 18 Sep 2023 10:14:42 -0700 Subject: [PATCH 34/46] https://telecominfraproject.atlassian.net/browse/WIFI-7831 Signed-off-by: stephb9959 --- openapi/openroaming_orion.yaml | 2 +- src/RESTAPI/RESTAPI_openroaming_orion_acct_handler.h | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/openapi/openroaming_orion.yaml b/openapi/openroaming_orion.yaml index d2cb132..0dd0e66 100644 --- a/openapi/openroaming_orion.yaml +++ b/openapi/openroaming_orion.yaml @@ -94,7 +94,7 @@ paths: 404: $ref: '#/components/responses/NotFound' - /openroaming/globalreach/account/{id}: + /openroaming/orion/account/{id}: get: tags: - OpenRoaming-Google Orion diff --git a/src/RESTAPI/RESTAPI_openroaming_orion_acct_handler.h b/src/RESTAPI/RESTAPI_openroaming_orion_acct_handler.h index a896b2b..a2bb597 100644 --- a/src/RESTAPI/RESTAPI_openroaming_orion_acct_handler.h +++ b/src/RESTAPI/RESTAPI_openroaming_orion_acct_handler.h @@ -16,6 +16,7 @@ namespace OpenWifi { std::vector{Poco::Net::HTTPRequest::HTTP_GET, Poco::Net::HTTPRequest::HTTP_DELETE, Poco::Net::HTTPRequest::HTTP_POST, + Poco::Net::HTTPRequest::HTTP_PUT, Poco::Net::HTTPRequest::HTTP_OPTIONS}, Server, TransactionId, Internal) {} static auto PathName() { return std::list{"/api/v1/openroaming/orion/account/{id}"}; }; From 1ce856f2225e83ed546d8e8d57db97a45bf52cf6 Mon Sep 17 00:00:00 2001 From: stephb9959 Date: Mon, 18 Sep 2023 10:17:21 -0700 Subject: [PATCH 35/46] https://telecominfraproject.atlassian.net/browse/WIFI-7831 Signed-off-by: stephb9959 --- src/RESTAPI/RESTAPI_openroaming_orion_acct_handler.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/RESTAPI/RESTAPI_openroaming_orion_acct_handler.cpp b/src/RESTAPI/RESTAPI_openroaming_orion_acct_handler.cpp index be839ad..a8c118e 100644 --- a/src/RESTAPI/RESTAPI_openroaming_orion_acct_handler.cpp +++ b/src/RESTAPI/RESTAPI_openroaming_orion_acct_handler.cpp @@ -69,7 +69,7 @@ namespace OpenWifi { } void RESTAPI_openroaming_orion_acct_handler::DoPut() { - auto Account = GetBinding("account",""); + auto Account = GetBinding("id",""); if(Account.empty()) { return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters); } From 5bdcbe84230d0706d7962b25e939aa0d49f9a8a2 Mon Sep 17 00:00:00 2001 From: stephb9959 Date: Mon, 18 Sep 2023 11:26:19 -0700 Subject: [PATCH 36/46] https://telecominfraproject.atlassian.net/browse/WIFI-7831 Signed-off-by: stephb9959 --- src/FileDownloader.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/FileDownloader.cpp b/src/FileDownloader.cpp index f16d430..533c052 100644 --- a/src/FileDownloader.cpp +++ b/src/FileDownloader.cpp @@ -24,9 +24,8 @@ namespace OpenWifi { void FileDownloader::onTimer([[maybe_unused]] Poco::Timer &timer) { const static std::vector> Files{ - {"https://raw.githubusercontent.com/blogic/ucentral-schema/main/ucentral.schema.json", - "ucentral.schema.json"}, - {"https://ucentral.io/ucentral.schema.pretty.json", "ucentral.schema.pretty.json"}}; + { "https://raw.githubusercontent.com/Telecominfraproject/wlan-ucentral-schema/main/ucentral.schema.json", + "ucentral.schema.json"} }; Utils::SetThreadName("file-dmnldr"); From 5b040d132f4b1327fe6a3b01108ec097f202ce94 Mon Sep 17 00:00:00 2001 From: stephb9959 Date: Tue, 19 Sep 2023 21:52:26 -0700 Subject: [PATCH 37/46] https://telecominfraproject.atlassian.net/browse/WIFI-12945 Signed-off-by: stephb9959 --- build | 2 +- src/framework/ConfigurationValidator.cpp | 233 ++++++++++++++++++----- 2 files changed, 187 insertions(+), 48 deletions(-) diff --git a/build b/build index d99e90e..8580e7b 100644 --- a/build +++ b/build @@ -1 +1 @@ -29 \ No newline at end of file +30 \ No newline at end of file diff --git a/src/framework/ConfigurationValidator.cpp b/src/framework/ConfigurationValidator.cpp index 00de09b..28b6e0c 100644 --- a/src/framework/ConfigurationValidator.cpp +++ b/src/framework/ConfigurationValidator.cpp @@ -28,11 +28,16 @@ static const std::string GitUCentralJSONSchemaFile{ "ucentral.schema.json"}; static std::string DefaultUCentralSchema = R"foo( + { "$id": "https://openwrt.org/ucentral.schema.json", "$schema": "http://json-schema.org/draft-07/schema#", "type": "object", "properties": { + "strict": { + "type": "boolean", + "default": false + }, "uuid": { "type": "integer" }, @@ -113,6 +118,20 @@ static std::string DefaultUCentralSchema = R"foo( "random-password": { "type": "boolean", "default": false + }, + "beacon-advertisement": { + "type": "object", + "properties": { + "device-name": { + "type": "boolean" + }, + "device-serial": { + "type": "boolean" + }, + "network-id": { + "type": "integer" + } + } } } }, @@ -221,6 +240,52 @@ static std::string DefaultUCentralSchema = R"foo( } } }, + "interface.ssid.encryption": { + "type": "object", + "properties": { + "proto": { + "type": "string", + "enum": [ + "none", + "owe", + "owe-transition", + "psk", + "psk2", + "psk-mixed", + "psk2-radius", + "wpa", + "wpa2", + "wpa-mixed", + "sae", + "sae-mixed", + "wpa3", + "wpa3-192", + "wpa3-mixed" + ], + "examples": [ + "psk2" + ] + }, + "key": { + "type": "string", + "maxLength": 63, + "minLength": 8 + }, + "ieee80211w": { + "type": "string", + "enum": [ + "disabled", + "optional", + "required" + ], + "default": "disabled" + }, + "key-caching": { + "type": "boolean", + "default": true + } + } + }, "definitions": { "type": "object", "properties": { @@ -715,7 +780,8 @@ static std::string DefaultUCentralSchema = R"foo( "type": "string", "enum": [ "dynamic", - "static" + "static", + "none" ], "examples": [ "static" @@ -1005,52 +1071,6 @@ static std::string DefaultUCentralSchema = R"foo( } ] }, - "interface.ssid.encryption": { - "type": "object", - "properties": { - "proto": { - "type": "string", - "enum": [ - "none", - "owe", - "owe-transition", - "psk", - "psk2", - "psk-mixed", - "psk2-radius", - "wpa", - "wpa2", - "wpa-mixed", - "sae", - "sae-mixed", - "wpa3", - "wpa3-192", - "wpa3-mixed" - ], - "examples": [ - "psk2" - ] - }, - "key": { - "type": "string", - "maxLength": 63, - "minLength": 8 - }, - "ieee80211w": { - "type": "string", - "enum": [ - "disabled", - "optional", - "required" - ], - "default": "disabled" - }, - "key-caching": { - "type": "boolean", - "default": true - } - } - }, "interface.ssid.multi-psk": { "type": "object", "properties": { @@ -2019,6 +2039,11 @@ static std::string DefaultUCentralSchema = R"foo( "decription": "This option allows embedding custom vendor specific IEs inside the beacons of a BSS in AP mode.", "type": "string" }, + "tip-information-element": { + "decription": "The device will broadcast the TIP vendor IE inside its beacons if this option is enabled.", + "type": "boolean", + "default": true + }, "fils-discovery-interval": { "type": "integer", "default": 20, @@ -2442,6 +2467,24 @@ static std::string DefaultUCentralSchema = R"foo( "type": "boolean", "default": false }, + "mode": { + "type": "string", + "enum": [ + "radius", + "user" + ] + }, + "port-filter": { + "type": "array", + "items": { + "type": "string", + "examples": [ + { + "LAN1": null + } + ] + } + }, "server-certificate": { "type": "string" }, @@ -2453,6 +2496,77 @@ static std::string DefaultUCentralSchema = R"foo( "items": { "$ref": "#/$defs/interface.ssid.radius.local-user" } + }, + "radius": { + "type": "object", + "properties": { + "nas-identifier": { + "type": "string" + }, + "auth-server-addr": { + "type": "string", + "format": "uc-host", + "examples": [ + "192.168.1.10" + ] + }, + "auth-server-port": { + "type": "integer", + "maximum": 65535, + "minimum": 1024, + "examples": [ + 1812 + ] + }, + "auth-server-secret": { + "type": "string", + "examples": [ + "secret" + ] + }, + "acct-server-addr": { + "type": "string", + "format": "uc-host", + "examples": [ + "192.168.1.10" + ] + }, + "acct-server-port": { + "type": "integer", + "maximum": 65535, + "minimum": 1024, + "examples": [ + 1813 + ] + }, + "acct-server-secret": { + "type": "string", + "examples": [ + "secret" + ] + }, + "coa-server-addr": { + "type": "string", + "format": "uc-host", + "examples": [ + "192.168.1.10" + ] + }, + "coa-server-port": { + "type": "integer", + "maximum": 65535, + "minimum": 1024, + "examples": [ + 1814 + ] + }, + "coa-server-secret": { + "type": "string", + "examples": [ + "secret" + ] + } + } } } }, @@ -2776,6 +2890,12 @@ static std::string DefaultUCentralSchema = R"foo( } } }, + "services": { + "type": "array", + "items": { + "type": "string" + } + }, "classifier": { "type": "array", "items": { @@ -3018,6 +3138,24 @@ static std::string DefaultUCentralSchema = R"foo( "relay-server": { "type": "string", "format": "uc-ip" + }, + "circuit-id-format": { + "type": "string", + "enum": [ + "vlan-id", + "ap-mac", + "ssid" + ], + "default": "vlan-id" + }, + "remote-id-format": { + "type": "string", + "enum": [ + "vlan-id", + "ap-mac", + "ssid" + ], + "default": "ap-mac" } } } @@ -3325,6 +3463,7 @@ static std::string DefaultUCentralSchema = R"foo( } } } + )foo"; static inline bool IsIPv4(const std::string &value) { From 19314815cd9b1354bbf9b9494d9cc33e3e5c1da5 Mon Sep 17 00:00:00 2001 From: stephb9959 Date: Fri, 22 Sep 2023 13:37:54 -0700 Subject: [PATCH 38/46] https://telecominfraproject.atlassian.net/browse/WIFI-12945 Signed-off-by: stephb9959 --- src/AutoDiscovery.cpp | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/src/AutoDiscovery.cpp b/src/AutoDiscovery.cpp index f536baa..d2a74fa 100644 --- a/src/AutoDiscovery.cpp +++ b/src/AutoDiscovery.cpp @@ -38,23 +38,33 @@ namespace OpenWifi { auto Msg = dynamic_cast(Note.get()); if (Msg != nullptr) { try { + DBGLINE Poco::JSON::Parser Parser; auto Object = Parser.parse(Msg->Payload()).extract(); + DBGLINE if (Object->has(uCentralProtocol::PAYLOAD)) { + DBGLINE auto PayloadObj = Object->getObject(uCentralProtocol::PAYLOAD); std::string ConnectedIP, SerialNumber, DeviceType; + DBGLINE if (PayloadObj->has(uCentralProtocol::CONNECTIONIP)) + DBGLINE ConnectedIP = PayloadObj->get(uCentralProtocol::CONNECTIONIP).toString(); if (PayloadObj->has(uCentralProtocol::CAPABILITIES)) { + DBGLINE auto CapObj = PayloadObj->getObject(uCentralProtocol::CAPABILITIES); if (CapObj->has(uCentralProtocol::COMPATIBLE)) { + DBGLINE DeviceType = CapObj->get(uCentralProtocol::COMPATIBLE).toString(); SerialNumber = PayloadObj->get(uCentralProtocol::SERIAL).toString(); + DBGLINE } } else if (PayloadObj->has(uCentralProtocol::PING)) { + DBGLINE auto PingMessage = PayloadObj->getObject(uCentralProtocol::PING); + DBGLINE if (PingMessage->has(uCentralProtocol::FIRMWARE) && PingMessage->has(uCentralProtocol::SERIALNUMBER) && PingMessage->has(uCentralProtocol::COMPATIBLE)) { @@ -65,24 +75,36 @@ namespace OpenWifi { PingMessage->get(uCentralProtocol::SERIALNUMBER).toString(); DeviceType = PingMessage->get(uCentralProtocol::COMPATIBLE).toString(); + DBGLINE } + DBGLINE } std::string Locale; - if (PayloadObj->has("locale")) - Locale = PayloadObj->get("locale").toString(); + if (PayloadObj->has("locale")) { + DBGLINE + Locale = PayloadObj->get("locale").toString(); + DBGLINE + } if (!SerialNumber.empty()) { + DBGLINE StorageService()->InventoryDB().CreateFromConnection( SerialNumber, ConnectedIP, DeviceType, Locale); } } } catch (const Poco::Exception &E) { + DBGLINE Logger().log(E); + DBGLINE } catch (...) { + DBGLINE } } else { + DBGLINE } + DBGLINE Note = Queue_.waitDequeueNotification(); + DBGLINE } } From 26fc29ac126ea964052ec9fc43cc4e24ee609a31 Mon Sep 17 00:00:00 2001 From: stephb9959 Date: Fri, 22 Sep 2023 13:42:19 -0700 Subject: [PATCH 39/46] https://telecominfraproject.atlassian.net/browse/WIFI-12945 Signed-off-by: stephb9959 --- src/AutoDiscovery.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/AutoDiscovery.cpp b/src/AutoDiscovery.cpp index d2a74fa..3f4359b 100644 --- a/src/AutoDiscovery.cpp +++ b/src/AutoDiscovery.cpp @@ -94,6 +94,7 @@ namespace OpenWifi { } } catch (const Poco::Exception &E) { DBGLINE + std::cout << Msg->Payload() << std::endl; Logger().log(E); DBGLINE } catch (...) { From 5a3ce590734a7573f05d06ff192081048ba66415 Mon Sep 17 00:00:00 2001 From: stephb9959 Date: Fri, 22 Sep 2023 13:57:30 -0700 Subject: [PATCH 40/46] https://telecominfraproject.atlassian.net/browse/WIFI-12945 Signed-off-by: stephb9959 --- src/AutoDiscovery.cpp | 90 ++++++++++++++++++++++--------------------- 1 file changed, 47 insertions(+), 43 deletions(-) diff --git a/src/AutoDiscovery.cpp b/src/AutoDiscovery.cpp index 3f4359b..65d3d6e 100644 --- a/src/AutoDiscovery.cpp +++ b/src/AutoDiscovery.cpp @@ -43,58 +43,62 @@ namespace OpenWifi { auto Object = Parser.parse(Msg->Payload()).extract(); DBGLINE + std::cout << Msg->Payload() << std::endl; if (Object->has(uCentralProtocol::PAYLOAD)) { DBGLINE - auto PayloadObj = Object->getObject(uCentralProtocol::PAYLOAD); - std::string ConnectedIP, SerialNumber, DeviceType; - DBGLINE - if (PayloadObj->has(uCentralProtocol::CONNECTIONIP)) - DBGLINE - ConnectedIP = - PayloadObj->get(uCentralProtocol::CONNECTIONIP).toString(); - if (PayloadObj->has(uCentralProtocol::CAPABILITIES)) { + auto PayloadObj = Object->getObject(uCentralProtocol::PAYLOAD); + if (PayloadObj->has("ping")) { + auto PingObj = PayloadObj->getObject("ping"); + std::string ConnectedIP, SerialNumber, DeviceType; DBGLINE - auto CapObj = PayloadObj->getObject(uCentralProtocol::CAPABILITIES); - if (CapObj->has(uCentralProtocol::COMPATIBLE)) { + if (PayloadObj->has(uCentralProtocol::CONNECTIONIP)) DBGLINE - DeviceType = CapObj->get(uCentralProtocol::COMPATIBLE).toString(); - SerialNumber = PayloadObj->get(uCentralProtocol::SERIAL).toString(); + ConnectedIP = + PayloadObj->get(uCentralProtocol::CONNECTIONIP).toString(); + if (PayloadObj->has(uCentralProtocol::CAPABILITIES)) { DBGLINE - } - } else if (PayloadObj->has(uCentralProtocol::PING)) { - DBGLINE - auto PingMessage = PayloadObj->getObject(uCentralProtocol::PING); - DBGLINE - if (PingMessage->has(uCentralProtocol::FIRMWARE) && - PingMessage->has(uCentralProtocol::SERIALNUMBER) && - PingMessage->has(uCentralProtocol::COMPATIBLE)) { - if (PingMessage->has(uCentralProtocol::CONNECTIONIP)) - ConnectedIP = - PingMessage->get(uCentralProtocol::CONNECTIONIP).toString(); - SerialNumber = - PingMessage->get(uCentralProtocol::SERIALNUMBER).toString(); - DeviceType = - PingMessage->get(uCentralProtocol::COMPATIBLE).toString(); + auto CapObj = PayloadObj->getObject(uCentralProtocol::CAPABILITIES); + if (CapObj->has(uCentralProtocol::COMPATIBLE)) { + DBGLINE + DeviceType = CapObj->get(uCentralProtocol::COMPATIBLE).toString(); + SerialNumber = PayloadObj->get(uCentralProtocol::SERIAL).toString(); + DBGLINE + } + } else if (PayloadObj->has(uCentralProtocol::PING)) { DBGLINE - } - DBGLINE - } - std::string Locale; - if (PayloadObj->has("locale")) { - DBGLINE - Locale = PayloadObj->get("locale").toString(); - DBGLINE - } + auto PingMessage = PayloadObj->getObject(uCentralProtocol::PING); + DBGLINE + if (PingMessage->has(uCentralProtocol::FIRMWARE) && + PingMessage->has(uCentralProtocol::SERIALNUMBER) && + PingMessage->has(uCentralProtocol::COMPATIBLE)) { + if (PingMessage->has(uCentralProtocol::CONNECTIONIP)) + ConnectedIP = + PingMessage->get(uCentralProtocol::CONNECTIONIP).toString(); + SerialNumber = + PingMessage->get(uCentralProtocol::SERIALNUMBER).toString(); + DeviceType = + PingMessage->get(uCentralProtocol::COMPATIBLE).toString(); + DBGLINE + } + DBGLINE + } + std::string Locale; + if (PayloadObj->has("locale")) { + DBGLINE + Locale = PayloadObj->get("locale").toString(); + DBGLINE + } - if (!SerialNumber.empty()) { - DBGLINE - StorageService()->InventoryDB().CreateFromConnection( - SerialNumber, ConnectedIP, DeviceType, Locale); - } - } + if (!SerialNumber.empty()) { + DBGLINE + StorageService()->InventoryDB().CreateFromConnection( + SerialNumber, ConnectedIP, DeviceType, Locale); + } + } + } } catch (const Poco::Exception &E) { DBGLINE - std::cout << Msg->Payload() << std::endl; + std::cout << "EX:" << Msg->Payload() << std::endl; Logger().log(E); DBGLINE } catch (...) { From c5737de2fc25cfae5da502476f923b08b30ef6d9 Mon Sep 17 00:00:00 2001 From: stephb9959 Date: Fri, 22 Sep 2023 21:59:18 -0700 Subject: [PATCH 41/46] https://telecominfraproject.atlassian.net/browse/WIFI-12945 Signed-off-by: stephb9959 --- CMakeLists.txt | 2 +- src/AutoDiscovery.cpp | 88 +++++++++++++++++++++---------------------- src/AutoDiscovery.h | 8 +++- 3 files changed, 51 insertions(+), 47 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 983d7d4..9264ccd 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -37,7 +37,7 @@ if(GIT_FOUND AND EXISTS "${PROJECT_SOURCE_DIR}/.git") string(REGEX REPLACE "\n$" "" GIT_HASH "${GIT_HASH}") endif() -add_definitions(-DAWS_CUSTOM_MEMORY_MANAGEMENT) +add_definitions(-DAWS_CUSTOM_MEMORY_MANAGEMENT -DBOOST_NO_CXX98_FUNCTION_BASE=1) find_package(OpenSSL REQUIRED) find_package(ZLIB REQUIRED) diff --git a/src/AutoDiscovery.cpp b/src/AutoDiscovery.cpp index 65d3d6e..ac5b9bb 100644 --- a/src/AutoDiscovery.cpp +++ b/src/AutoDiscovery.cpp @@ -31,6 +31,39 @@ namespace OpenWifi { poco_information(Logger(), "Stopped..."); }; + void AutoDiscovery::ProcessPing(const Poco::JSON::Object::Ptr & P, std::string &FW, std::string &SN, + std::string &Compat, std::string &Conn, std::string &locale) { + if (P->has(uCentralProtocol::CONNECTIONIP)) + Conn = P->get(uCentralProtocol::CONNECTIONIP).toString(); + if (P->has(uCentralProtocol::FIRMWARE)) + FW = P->get(uCentralProtocol::FIRMWARE).toString(); + if (P->has(uCentralProtocol::SERIALNUMBER)) + SN = P->get(uCentralProtocol::SERIALNUMBER).toString(); + if (P->has(uCentralProtocol::COMPATIBLE)) + Compat = P->get(uCentralProtocol::COMPATIBLE).toString(); + if (P->has("locale")) { + locale = P->get("locale").toString(); + } + } + + void AutoDiscovery::ProcessConnect(const Poco::JSON::Object::Ptr &P, std::string &FW, std::string &SN, + std::string &Compat, std::string &Conn, std::string &locale) { + if (P->has(uCentralProtocol::CONNECTIONIP)) + Conn = P->get(uCentralProtocol::CONNECTIONIP).toString(); + if (P->has(uCentralProtocol::FIRMWARE)) + FW = P->get(uCentralProtocol::FIRMWARE).toString(); + if (P->has(uCentralProtocol::SERIALNUMBER)) + SN = P->get(uCentralProtocol::SERIALNUMBER).toString(); + if (P->has("locale")) { + locale = P->get("locale").toString(); + } + if(P->has(uCentralProtocol::CAPABILITIES)) { + auto CapObj = P->getObject(uCentralProtocol::CAPABILITIES); + if (CapObj->has(uCentralProtocol::COMPATIBLE)) + Compat = CapObj->get(uCentralProtocol::COMPATIBLE).toString(); + } + } + void AutoDiscovery::run() { Poco::AutoPtr Note(Queue_.waitDequeueNotification()); Utils::SetThreadName("auto-discovery"); @@ -47,53 +80,18 @@ namespace OpenWifi { if (Object->has(uCentralProtocol::PAYLOAD)) { DBGLINE auto PayloadObj = Object->getObject(uCentralProtocol::PAYLOAD); - if (PayloadObj->has("ping")) { + std::string ConnectedIP, SerialNumber, Compatible, Firmware, Locale ; + if (PayloadObj->has(uCentralProtocol::PING)) { auto PingObj = PayloadObj->getObject("ping"); - std::string ConnectedIP, SerialNumber, DeviceType; - DBGLINE - if (PayloadObj->has(uCentralProtocol::CONNECTIONIP)) - DBGLINE - ConnectedIP = - PayloadObj->get(uCentralProtocol::CONNECTIONIP).toString(); - if (PayloadObj->has(uCentralProtocol::CAPABILITIES)) { - DBGLINE - auto CapObj = PayloadObj->getObject(uCentralProtocol::CAPABILITIES); - if (CapObj->has(uCentralProtocol::COMPATIBLE)) { - DBGLINE - DeviceType = CapObj->get(uCentralProtocol::COMPATIBLE).toString(); - SerialNumber = PayloadObj->get(uCentralProtocol::SERIAL).toString(); - DBGLINE - } - } else if (PayloadObj->has(uCentralProtocol::PING)) { - DBGLINE - auto PingMessage = PayloadObj->getObject(uCentralProtocol::PING); - DBGLINE - if (PingMessage->has(uCentralProtocol::FIRMWARE) && - PingMessage->has(uCentralProtocol::SERIALNUMBER) && - PingMessage->has(uCentralProtocol::COMPATIBLE)) { - if (PingMessage->has(uCentralProtocol::CONNECTIONIP)) - ConnectedIP = - PingMessage->get(uCentralProtocol::CONNECTIONIP).toString(); - SerialNumber = - PingMessage->get(uCentralProtocol::SERIALNUMBER).toString(); - DeviceType = - PingMessage->get(uCentralProtocol::COMPATIBLE).toString(); - DBGLINE - } - DBGLINE - } - std::string Locale; - if (PayloadObj->has("locale")) { - DBGLINE - Locale = PayloadObj->get("locale").toString(); - DBGLINE - } + ProcessPing(PingObj, Firmware, SerialNumber, Compatible, ConnectedIP, Locale); + } else if(PayloadObj->has("capabilities")) { + ProcessConnect(PayloadObj, Firmware, SerialNumber, Compatible, ConnectedIP, Locale); + } - if (!SerialNumber.empty()) { - DBGLINE - StorageService()->InventoryDB().CreateFromConnection( - SerialNumber, ConnectedIP, DeviceType, Locale); - } + if (!SerialNumber.empty()) { + DBGLINE + StorageService()->InventoryDB().CreateFromConnection( + SerialNumber, ConnectedIP, Compatible, Locale); } } } catch (const Poco::Exception &E) { diff --git a/src/AutoDiscovery.h b/src/AutoDiscovery.h index f6d6ed4..87a3af1 100644 --- a/src/AutoDiscovery.h +++ b/src/AutoDiscovery.h @@ -9,6 +9,7 @@ #include "Poco/Notification.h" #include "Poco/NotificationQueue.h" +#include "Poco/JSON/Object.h" namespace OpenWifi { @@ -46,7 +47,12 @@ namespace OpenWifi { Poco::Thread Worker_; std::atomic_bool Running_ = false; - AutoDiscovery() noexcept + void ProcessPing(const Poco::JSON::Object::Ptr & P, std::string &FW, std::string &SN, + std::string &Compat, std::string &Conn, std::string &locale) ; + void ProcessConnect(const Poco::JSON::Object::Ptr & P, std::string &FW, std::string &SN, + std::string &Compat, std::string &Conn, std::string &locale) ; + + AutoDiscovery() noexcept : SubSystemServer("AutoDiscovery", "AUTO-DISCOVERY", "discovery") {} }; From 1948c50ad45c7059f0bfb9e42222ac2e1886e228 Mon Sep 17 00:00:00 2001 From: stephb9959 Date: Fri, 22 Sep 2023 22:04:27 -0700 Subject: [PATCH 42/46] https://telecominfraproject.atlassian.net/browse/WIFI-12945 Signed-off-by: stephb9959 --- src/AutoDiscovery.cpp | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/src/AutoDiscovery.cpp b/src/AutoDiscovery.cpp index ac5b9bb..6072825 100644 --- a/src/AutoDiscovery.cpp +++ b/src/AutoDiscovery.cpp @@ -71,14 +71,11 @@ namespace OpenWifi { auto Msg = dynamic_cast(Note.get()); if (Msg != nullptr) { try { - DBGLINE Poco::JSON::Parser Parser; auto Object = Parser.parse(Msg->Payload()).extract(); - DBGLINE std::cout << Msg->Payload() << std::endl; if (Object->has(uCentralProtocol::PAYLOAD)) { - DBGLINE auto PayloadObj = Object->getObject(uCentralProtocol::PAYLOAD); std::string ConnectedIP, SerialNumber, Compatible, Firmware, Locale ; if (PayloadObj->has(uCentralProtocol::PING)) { @@ -86,28 +83,23 @@ namespace OpenWifi { ProcessPing(PingObj, Firmware, SerialNumber, Compatible, ConnectedIP, Locale); } else if(PayloadObj->has("capabilities")) { ProcessConnect(PayloadObj, Firmware, SerialNumber, Compatible, ConnectedIP, Locale); + } else { + std::cout << Msg->Payload() << std::endl; } if (!SerialNumber.empty()) { - DBGLINE StorageService()->InventoryDB().CreateFromConnection( SerialNumber, ConnectedIP, Compatible, Locale); } } } catch (const Poco::Exception &E) { - DBGLINE std::cout << "EX:" << Msg->Payload() << std::endl; Logger().log(E); - DBGLINE } catch (...) { - DBGLINE } } else { - DBGLINE } - DBGLINE Note = Queue_.waitDequeueNotification(); - DBGLINE } } From ca1cf64fa2eff6d954f6d0e3c3fcd119f29ad644 Mon Sep 17 00:00:00 2001 From: stephb9959 Date: Fri, 22 Sep 2023 22:06:17 -0700 Subject: [PATCH 43/46] https://telecominfraproject.atlassian.net/browse/WIFI-12945 Signed-off-by: stephb9959 --- src/AutoDiscovery.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/AutoDiscovery.cpp b/src/AutoDiscovery.cpp index 6072825..ef336fb 100644 --- a/src/AutoDiscovery.cpp +++ b/src/AutoDiscovery.cpp @@ -74,7 +74,6 @@ namespace OpenWifi { Poco::JSON::Parser Parser; auto Object = Parser.parse(Msg->Payload()).extract(); - std::cout << Msg->Payload() << std::endl; if (Object->has(uCentralProtocol::PAYLOAD)) { auto PayloadObj = Object->getObject(uCentralProtocol::PAYLOAD); std::string ConnectedIP, SerialNumber, Compatible, Firmware, Locale ; From ba46c1558c9a1db8859cd7032c5c04eb2a09ae84 Mon Sep 17 00:00:00 2001 From: stephb9959 Date: Fri, 22 Sep 2023 22:28:07 -0700 Subject: [PATCH 44/46] https://telecominfraproject.atlassian.net/browse/WIFI-12945 Signed-off-by: stephb9959 --- src/framework/KafkaManager.cpp | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/src/framework/KafkaManager.cpp b/src/framework/KafkaManager.cpp index d32833e..d903652 100644 --- a/src/framework/KafkaManager.cpp +++ b/src/framework/KafkaManager.cpp @@ -99,9 +99,12 @@ namespace OpenWifi { try { auto Msg = dynamic_cast(Note.get()); if (Msg != nullptr) { - Producer.produce(cppkafka::MessageBuilder(Msg->Topic()) - .key(Msg->Key()) - .payload(Msg->Payload())); + auto NewMessage = cppkafka::MessageBuilder(Msg->Topic()); + NewMessage.key(Msg->Key()); + NewMessage.partition(0); + NewMessage.payload(Msg->Payload()); + Producer.produce(NewMessage); + Producer.flush(); } } catch (const cppkafka::HandleException &E) { poco_warning(Logger_, @@ -157,17 +160,19 @@ namespace OpenWifi { }); bool AutoCommit = MicroServiceConfigGetBool("openwifi.kafka.auto.commit", false); - auto BatchSize = MicroServiceConfigGetInt("openwifi.kafka.consumer.batchsize", 20); + auto BatchSize = MicroServiceConfigGetInt("openwifi.kafka.consumer.batchsize", 100); Types::StringVec Topics; KafkaManager()->Topics(Topics); Consumer.subscribe(Topics); Running_ = true; + std::vector MsgVec; while (Running_) { try { - std::vector MsgVec = - Consumer.poll_batch(BatchSize, std::chrono::milliseconds(100)); + MsgVec.clear(); + MsgVec.reserve(BatchSize); + MsgVec = Consumer.poll_batch(BatchSize, std::chrono::milliseconds(1000)); for (auto const &Msg : MsgVec) { if (!Msg) continue; @@ -177,12 +182,12 @@ namespace OpenWifi { fmt::format("Error: {}", Msg.get_error().to_string())); } if (!AutoCommit) - Consumer.async_commit(Msg); + Consumer.commit(Msg); continue; } KafkaManager()->Dispatch(Msg.get_topic().c_str(), Msg.get_key(), Msg.get_payload()); if (!AutoCommit) - Consumer.async_commit(Msg); + Consumer.commit(Msg); } } catch (const cppkafka::HandleException &E) { poco_warning(Logger_, @@ -355,7 +360,10 @@ namespace OpenWifi { } [[nodiscard]] std::string KafkaManager::WrapSystemId(const std::string & PayLoad) { - return SystemInfoWrapper_ + PayLoad + "}"; + return fmt::format( R"lit({{ "system" : {{ "id" : {}, + "host" : "{}" }}, + "payload" : {} }})lit", MicroServiceID(), + MicroServicePrivateEndPoint(), PayLoad ) ; } uint64_t KafkaManager::RegisterTopicWatcher(const std::string &Topic, From 1d077b945d4b7c48d829fe33322ffcaabbe8b754 Mon Sep 17 00:00:00 2001 From: stephb9959 Date: Sat, 23 Sep 2023 15:23:13 -0700 Subject: [PATCH 45/46] https://telecominfraproject.atlassian.net/browse/WIFI-12954 Signed-off-by: stephb9959 --- build | 2 +- src/AutoDiscovery.cpp | 20 +++++++++++++++++--- src/AutoDiscovery.h | 2 ++ 3 files changed, 20 insertions(+), 4 deletions(-) diff --git a/build b/build index 8580e7b..b74e882 100644 --- a/build +++ b/build @@ -1 +1 @@ -30 \ No newline at end of file +31 \ No newline at end of file diff --git a/src/AutoDiscovery.cpp b/src/AutoDiscovery.cpp index ef336fb..be9e6bc 100644 --- a/src/AutoDiscovery.cpp +++ b/src/AutoDiscovery.cpp @@ -64,7 +64,16 @@ namespace OpenWifi { } } - void AutoDiscovery::run() { + void AutoDiscovery::ProcessDisconnect(const Poco::JSON::Object::Ptr &P, [[maybe_unused]] std::string &FW, + std::string &SN, + [[maybe_unused]] std::string &Compat, + [[maybe_unused]] std::string &Conn, + [[maybe_unused]] std::string &locale) { + if (P->has(uCentralProtocol::SERIALNUMBER)) + SN = P->get(uCentralProtocol::SERIALNUMBER).toString(); + } + + void AutoDiscovery::run() { Poco::AutoPtr Note(Queue_.waitDequeueNotification()); Utils::SetThreadName("auto-discovery"); while (Note && Running_) { @@ -73,6 +82,7 @@ namespace OpenWifi { try { Poco::JSON::Parser Parser; auto Object = Parser.parse(Msg->Payload()).extract(); + bool Connected=true; if (Object->has(uCentralProtocol::PAYLOAD)) { auto PayloadObj = Object->getObject(uCentralProtocol::PAYLOAD); @@ -82,11 +92,15 @@ namespace OpenWifi { ProcessPing(PingObj, Firmware, SerialNumber, Compatible, ConnectedIP, Locale); } else if(PayloadObj->has("capabilities")) { ProcessConnect(PayloadObj, Firmware, SerialNumber, Compatible, ConnectedIP, Locale); + } else if(PayloadObj->has("disconnection")) { + // we ignore disconnection in provisioning + Connected=false; + ProcessConnect(PayloadObj, Firmware, SerialNumber, Compatible, ConnectedIP, Locale); } else { - std::cout << Msg->Payload() << std::endl; + poco_debug(Logger(),fmt::format("Unknown message on 'connection' topic: {}",Msg->Payload())); } - if (!SerialNumber.empty()) { + if (!SerialNumber.empty() && Connected) { StorageService()->InventoryDB().CreateFromConnection( SerialNumber, ConnectedIP, Compatible, Locale); } diff --git a/src/AutoDiscovery.h b/src/AutoDiscovery.h index 87a3af1..05847f6 100644 --- a/src/AutoDiscovery.h +++ b/src/AutoDiscovery.h @@ -51,6 +51,8 @@ namespace OpenWifi { std::string &Compat, std::string &Conn, std::string &locale) ; void ProcessConnect(const Poco::JSON::Object::Ptr & P, std::string &FW, std::string &SN, std::string &Compat, std::string &Conn, std::string &locale) ; + void ProcessDisconnect(const Poco::JSON::Object::Ptr & P, std::string &FW, std::string &SN, + std::string &Compat, std::string &Conn, std::string &locale) ; AutoDiscovery() noexcept : SubSystemServer("AutoDiscovery", "AUTO-DISCOVERY", "discovery") {} From e71b83ced7e3a64a045329f2b8f36af95d80ac1b Mon Sep 17 00:00:00 2001 From: stephb9959 Date: Sun, 24 Sep 2023 10:54:45 -0700 Subject: [PATCH 46/46] https://telecominfraproject.atlassian.net/browse/WIFI-12954 Signed-off-by: stephb9959 --- build | 2 +- src/framework/KafkaManager.cpp | 154 +++++++++------------------------ src/framework/KafkaManager.h | 42 ++++----- 3 files changed, 59 insertions(+), 139 deletions(-) diff --git a/build b/build index b74e882..1758ddd 100644 --- a/build +++ b/build @@ -1 +1 @@ -31 \ No newline at end of file +32 \ No newline at end of file diff --git a/src/framework/KafkaManager.cpp b/src/framework/KafkaManager.cpp index d903652..9381065 100644 --- a/src/framework/KafkaManager.cpp +++ b/src/framework/KafkaManager.cpp @@ -6,6 +6,7 @@ #include "fmt/format.h" #include "framework/MicroServiceFuncs.h" +#include "cppkafka/utils/consumer_dispatcher.h" namespace OpenWifi { @@ -159,45 +160,49 @@ namespace OpenWifi { } }); - bool AutoCommit = MicroServiceConfigGetBool("openwifi.kafka.auto.commit", false); - auto BatchSize = MicroServiceConfigGetInt("openwifi.kafka.consumer.batchsize", 100); + // bool AutoCommit = MicroServiceConfigGetBool("openwifi.kafka.auto.commit", false); + // auto BatchSize = MicroServiceConfigGetInt("openwifi.kafka.consumer.batchsize", 100); Types::StringVec Topics; - KafkaManager()->Topics(Topics); + std::for_each(Topics_.begin(),Topics_.end(), + [&](const std::string & T) { Topics.emplace_back(T); }); Consumer.subscribe(Topics); Running_ = true; std::vector MsgVec; - while (Running_) { - try { - MsgVec.clear(); - MsgVec.reserve(BatchSize); - MsgVec = Consumer.poll_batch(BatchSize, std::chrono::milliseconds(1000)); - for (auto const &Msg : MsgVec) { - if (!Msg) - continue; - if (Msg.get_error()) { - if (!Msg.is_eof()) { - poco_error(Logger_, - fmt::format("Error: {}", Msg.get_error().to_string())); + + Dispatcher_ = std::make_unique(Consumer); + + Dispatcher_->run( + // Callback executed whenever a new message is consumed + [&](cppkafka::Message msg) { + // Print the key (if any) + std::lock_guard G(ConsumerMutex_); + auto It = Notifiers_.find(msg.get_topic()); + if (It != Notifiers_.end()) { + const auto &FL = It->second; + for (const auto &[CallbackFunc, _] : FL) { + try { + CallbackFunc(msg.get_key(), msg.get_payload()); + } catch(const Poco::Exception &E) { + + } catch(...) { + } - if (!AutoCommit) - Consumer.commit(Msg); - continue; } - KafkaManager()->Dispatch(Msg.get_topic().c_str(), Msg.get_key(), Msg.get_payload()); - if (!AutoCommit) - Consumer.commit(Msg); } - } catch (const cppkafka::HandleException &E) { - poco_warning(Logger_, - fmt::format("Caught a Kafka exception (consumer): {}", E.what())); - } catch (const Poco::Exception &E) { - Logger_.log(E); - } catch (...) { - poco_error(Logger_, "std::exception"); + Consumer.commit(msg); + }, + // Whenever there's an error (other than the EOF soft error) + [&Logger_](cppkafka::Error error) { + poco_warning(Logger_,fmt::format("Error: {}", error.to_string())); + }, + // Whenever EOF is reached on a partition, print this + [&Logger_](cppkafka::ConsumerDispatcher::EndOfFile, const cppkafka::TopicPartition& topic_partition) { + poco_debug(Logger_,fmt::format("Partition {} EOF", topic_partition.get_partition())); } - } + ); + Consumer.unsubscribe(); poco_information(Logger_, "Stopped..."); } @@ -225,7 +230,6 @@ namespace OpenWifi { void KafkaConsumer::Start() { if (!Running_) { - Running_ = true; Worker_.start(*this); } } @@ -233,29 +237,16 @@ namespace OpenWifi { void KafkaConsumer::Stop() { if (Running_) { Running_ = false; - Worker_.wakeUp(); - Worker_.join(); - } - } - - void KafkaDispatcher::Start() { - if (!Running_) { - Running_ = true; - Worker_.start(*this); - } - } - - void KafkaDispatcher::Stop() { - if (Running_) { - Running_ = false; - Queue_.wakeUpAll(); + if(Dispatcher_) { + Dispatcher_->stop(); + } Worker_.join(); } } - auto KafkaDispatcher::RegisterTopicWatcher(const std::string &Topic, + std::uint64_t KafkaConsumer::RegisterTopicWatcher(const std::string &Topic, Types::TopicNotifyFunction &F) { - std::lock_guard G(Mutex_); + std::lock_guard G(ConsumerMutex_); auto It = Notifiers_.find(Topic); if (It == Notifiers_.end()) { Types::TopicNotifyFunctionList L; @@ -264,11 +255,12 @@ namespace OpenWifi { } else { It->second.emplace(It->second.end(), std::make_pair(F, FunctionId_)); } + Topics_.insert(Topic); return FunctionId_++; } - void KafkaDispatcher::UnregisterTopicWatcher(const std::string &Topic, int Id) { - std::lock_guard G(Mutex_); + void KafkaConsumer::UnregisterTopicWatcher(const std::string &Topic, int Id) { + std::lock_guard G(ConsumerMutex_); auto It = Notifiers_.find(Topic); if (It != Notifiers_.end()) { Types::TopicNotifyFunctionList &L = It->second; @@ -280,56 +272,17 @@ namespace OpenWifi { } } - void KafkaDispatcher::Dispatch(const char *Topic, const std::string &Key, - const std::string & Payload) { - std::lock_guard G(Mutex_); - auto It = Notifiers_.find(Topic); - if (It != Notifiers_.end()) { - Queue_.enqueueNotification(new KafkaMessage(Topic, Key, Payload)); - } - } - - void KafkaDispatcher::run() { - Poco::Logger &Logger_ = - Poco::Logger::create("KAFKA-DISPATCHER", KafkaManager()->Logger().getChannel()); - poco_information(Logger_, "Starting..."); - Poco::AutoPtr Note(Queue_.waitDequeueNotification()); - Utils::SetThreadName("kafka:dispatch"); - while (Note && Running_) { - auto Msg = dynamic_cast(Note.get()); - if (Msg != nullptr) { - auto It = Notifiers_.find(Msg->Topic()); - if (It != Notifiers_.end()) { - const auto &FL = It->second; - for (const auto &[CallbackFunc, _] : FL) { - CallbackFunc(Msg->Key(), Msg->Payload()); - } - } - } - Note = Queue_.waitDequeueNotification(); - } - poco_information(Logger_, "Stopped..."); - } - - void KafkaDispatcher::Topics(std::vector &T) { - T.clear(); - for (const auto &[TopicName, _] : Notifiers_) - T.push_back(TopicName); - } - int KafkaManager::Start() { if (!KafkaEnabled_) return 0; ConsumerThr_.Start(); ProducerThr_.Start(); - Dispatcher_.Start(); return 0; } void KafkaManager::Stop() { if (KafkaEnabled_) { poco_information(Logger(), "Stopping..."); - Dispatcher_.Stop(); ProducerThr_.Stop(); ConsumerThr_.Stop(); poco_information(Logger(), "Stopped..."); @@ -353,12 +306,6 @@ namespace OpenWifi { } } - - void KafkaManager::Dispatch(const char *Topic, const std::string &Key, - const std::string &Payload) { - Dispatcher_.Dispatch(Topic, Key, Payload); - } - [[nodiscard]] std::string KafkaManager::WrapSystemId(const std::string & PayLoad) { return fmt::format( R"lit({{ "system" : {{ "id" : {}, "host" : "{}" }}, @@ -366,23 +313,6 @@ namespace OpenWifi { MicroServicePrivateEndPoint(), PayLoad ) ; } - uint64_t KafkaManager::RegisterTopicWatcher(const std::string &Topic, - Types::TopicNotifyFunction &F) { - if (KafkaEnabled_) { - return Dispatcher_.RegisterTopicWatcher(Topic, F); - } else { - return 0; - } - } - - void KafkaManager::UnregisterTopicWatcher(const std::string &Topic, uint64_t Id) { - if (KafkaEnabled_) { - Dispatcher_.UnregisterTopicWatcher(Topic, Id); - } - } - - void KafkaManager::Topics(std::vector &T) { Dispatcher_.Topics(T); } - void KafkaManager::PartitionAssignment(const cppkafka::TopicPartitionList &partitions) { poco_information( Logger(), fmt::format("Partition assigned: {}...", partitions.front().get_partition())); diff --git a/src/framework/KafkaManager.h b/src/framework/KafkaManager.h index 31cf093..e6272d3 100644 --- a/src/framework/KafkaManager.h +++ b/src/framework/KafkaManager.h @@ -39,7 +39,7 @@ namespace OpenWifi { void Produce(const char *Topic, const std::string &Key, const std::string & Payload); private: - std::recursive_mutex Mutex_; + std::mutex Mutex_; Poco::Thread Worker_; mutable std::atomic_bool Running_ = false; Poco::NotificationQueue Queue_; @@ -47,33 +47,22 @@ namespace OpenWifi { class KafkaConsumer : public Poco::Runnable { public: - void run() override; void Start(); void Stop(); private: - std::recursive_mutex Mutex_; - Poco::Thread Worker_; + std::mutex ConsumerMutex_; + Types::NotifyTable Notifiers_; + Poco::Thread Worker_; mutable std::atomic_bool Running_ = false; - }; + uint64_t FunctionId_ = 1; + std::unique_ptr Dispatcher_; + std::set Topics_; - class KafkaDispatcher : public Poco::Runnable { - public: - void Start(); - void Stop(); - auto RegisterTopicWatcher(const std::string &Topic, Types::TopicNotifyFunction &F); - void UnregisterTopicWatcher(const std::string &Topic, int Id); - void Dispatch(const char *Topic, const std::string &Key, const std::string & Payload); void run() override; - void Topics(std::vector &T); - - private: - std::recursive_mutex Mutex_; - Types::NotifyTable Notifiers_; - Poco::Thread Worker_; - mutable std::atomic_bool Running_ = false; - uint64_t FunctionId_ = 1; - Poco::NotificationQueue Queue_; + friend class KafkaManager; + std::uint64_t RegisterTopicWatcher(const std::string &Topic, Types::TopicNotifyFunction &F); + void UnregisterTopicWatcher(const std::string &Topic, int Id); }; class KafkaManager : public SubSystemServer { @@ -96,19 +85,20 @@ namespace OpenWifi { void PostMessage(const char *topic, const std::string &key, const Poco::JSON::Object &Object, bool WrapMessage = true); - void Dispatch(const char *Topic, const std::string &Key, const std::string &Payload); [[nodiscard]] std::string WrapSystemId(const std::string & PayLoad); [[nodiscard]] inline bool Enabled() const { return KafkaEnabled_; } - uint64_t RegisterTopicWatcher(const std::string &Topic, Types::TopicNotifyFunction &F); - void UnregisterTopicWatcher(const std::string &Topic, uint64_t Id); - void Topics(std::vector &T); + inline std::uint64_t RegisterTopicWatcher(const std::string &Topic, Types::TopicNotifyFunction &F) { + return ConsumerThr_.RegisterTopicWatcher(Topic,F); + } + inline void UnregisterTopicWatcher(const std::string &Topic, uint64_t Id) { + return ConsumerThr_.UnregisterTopicWatcher(Topic,Id); + } private: bool KafkaEnabled_ = false; std::string SystemInfoWrapper_; KafkaProducer ProducerThr_; KafkaConsumer ConsumerThr_; - KafkaDispatcher Dispatcher_; void PartitionAssignment(const cppkafka::TopicPartitionList &partitions); void PartitionRevocation(const cppkafka::TopicPartitionList &partitions);