diff --git a/build b/build index 8e2afd3..25bf17f 100644 --- a/build +++ b/build @@ -1 +1 @@ -17 \ No newline at end of file +18 \ No newline at end of file diff --git a/src/AuthService.cpp b/src/AuthService.cpp index 36bb32c..0f21ed9 100644 --- a/src/AuthService.cpp +++ b/src/AuthService.cpp @@ -43,8 +43,6 @@ namespace OpenWifi { } int AuthService::Start() { - Signer_.setRSAKey(MicroService::instance().Key()); - Signer_.addAllAlgorithms(); Logger().notice("Starting..."); TokenAging_ = (uint64_t) MicroService::instance().ConfigGetInt("authentication.token.ageing", 30 * 24 * 60 * 60); HowManyOldPassword_ = MicroService::instance().ConfigGetInt("authentication.oldpasswords", 5); @@ -225,7 +223,7 @@ namespace OpenWifi { T.payload().set("identity", Identity); T.setIssuedAt(Poco::Timestamp()); T.setExpiration(Poco::Timestamp() + (long long)TokenAging_); - std::string JWT = Signer_.sign(T,Poco::JWT::Signer::ALGO_RS256); + std::string JWT = MicroService::instance().Sign(T,Poco::JWT::Signer::ALGO_RS256); return JWT; } diff --git a/src/AuthService.h b/src/AuthService.h index edf0563..88cf326 100644 --- a/src/AuthService.h +++ b/src/AuthService.h @@ -114,7 +114,6 @@ namespace OpenWifi{ inline const std::string & GetSubAccessPolicy() const { return SubAccessPolicy_; } private: - Poco::JWT::Signer Signer_; Poco::SHA2Engine SHA2_; std::string AccessPolicy_; diff --git a/src/RESTObjects/RESTAPI_ProvObjects.cpp b/src/RESTObjects/RESTAPI_ProvObjects.cpp index 66df8eb..68a8172 100644 --- a/src/RESTObjects/RESTAPI_ProvObjects.cpp +++ b/src/RESTObjects/RESTAPI_ProvObjects.cpp @@ -328,13 +328,13 @@ namespace OpenWifi::ProvObjects { field_to_json( Obj, "geoCode", geoCode); field_to_json( Obj, "location", location); field_to_json( Obj, "contact", contact); - field_to_json( Obj,"deviceConfiguration",deviceConfiguration); - field_to_json( Obj,"rrm",rrm); - field_to_json( Obj,"managementPolicy",managementPolicy); - field_to_json( Obj,"state",state); - field_to_json( Obj,"devClass",devClass); - field_to_json( Obj,"locale",locale); - field_to_json( Obj,"realMacAddress",realMacAddress); + field_to_json( Obj, "deviceConfiguration",deviceConfiguration); + field_to_json( Obj, "rrm",rrm); + field_to_json( Obj, "managementPolicy",managementPolicy); + field_to_json( Obj, "state",state); + field_to_json( Obj, "devClass",devClass); + field_to_json( Obj, "locale",locale); + field_to_json( Obj, "realMacAddress",realMacAddress); } bool InventoryTag::from_json(const Poco::JSON::Object::Ptr &Obj) { @@ -345,7 +345,7 @@ namespace OpenWifi::ProvObjects { field_from_json( Obj,"entity",entity); field_from_json( Obj,"subscriber",subscriber); field_from_json( Obj,"deviceType",deviceType); - field_from_json( Obj, "qrCode", qrCode); + field_from_json( Obj,"qrCode", qrCode); field_from_json( Obj,"geoCode",geoCode); field_from_json( Obj,"location",location); field_from_json( Obj,"contact",contact); @@ -356,7 +356,6 @@ namespace OpenWifi::ProvObjects { field_from_json( Obj,"devClass",devClass); field_from_json( Obj,"locale",locale); field_from_json( Obj,"realMacAddress",realMacAddress); - return true; } catch(...) { @@ -771,6 +770,25 @@ namespace OpenWifi::ProvObjects { return false; } + void VenueDeviceList::to_json(Poco::JSON::Object &Obj) const { + RESTAPI_utils::field_to_json(Obj,"id",id); + RESTAPI_utils::field_to_json(Obj,"name",name); + RESTAPI_utils::field_to_json(Obj,"description",description); + RESTAPI_utils::field_to_json(Obj,"devices",devices); + } + + bool VenueDeviceList::from_json(const Poco::JSON::Object::Ptr &Obj) { + try { + RESTAPI_utils::field_from_json(Obj,"id",id); + RESTAPI_utils::field_from_json(Obj,"name",name); + RESTAPI_utils::field_from_json(Obj,"description",description); + RESTAPI_utils::field_from_json(Obj,"devices",devices); + return true; + } catch(...) { + + } + return false; + } bool UpdateObjectInfo(const Poco::JSON::Object::Ptr &O, const SecurityObjects::UserInfo &U, ObjectInfo &I) { uint64_t Now = std::time(nullptr); diff --git a/src/RESTObjects/RESTAPI_ProvObjects.h b/src/RESTObjects/RESTAPI_ProvObjects.h index 5839221..0642484 100644 --- a/src/RESTObjects/RESTAPI_ProvObjects.h +++ b/src/RESTObjects/RESTAPI_ProvObjects.h @@ -480,6 +480,17 @@ namespace OpenWifi::ProvObjects { bool from_json(const Poco::JSON::Object::Ptr &Obj); }; + struct VenueDeviceList { + std::string id; + std::string name; + std::string description; + Types::UUIDvec_t devices; + + void to_json(Poco::JSON::Object &Obj) const; + bool from_json(const Poco::JSON::Object::Ptr &Obj); + }; + + bool UpdateObjectInfo(const Poco::JSON::Object::Ptr &O, const SecurityObjects::UserInfo &U, ObjectInfo &I); bool CreateObjectInfo(const Poco::JSON::Object::Ptr &O, const SecurityObjects::UserInfo &U, ObjectInfo &I); bool CreateObjectInfo(const SecurityObjects::UserInfo &U, ObjectInfo &I); diff --git a/src/framework/MicroService.h b/src/framework/MicroService.h index 9dc0201..cc75328 100644 --- a/src/framework/MicroService.h +++ b/src/framework/MicroService.h @@ -71,6 +71,7 @@ using namespace std::chrono_literals; #include "Poco/SimpleFileChannel.h" #include "Poco/Util/PropertyFileConfiguration.h" #include "Poco/SplitterChannel.h" +#include "Poco/JWT/Signer.h" #include "cppkafka/cppkafka.h" @@ -280,6 +281,11 @@ namespace OpenWifi::RESTAPI_utils { S = Obj->get(Field).toString(); } + inline void field_from_json(Poco::JSON::Object::Ptr Obj, const char *Field, double & V) { + if(Obj->has(Field)) + V = Obj->get(Field); + } + inline void field_from_json(Poco::JSON::Object::Ptr Obj, const char *Field, uint64_t &V) { if(Obj->has(Field)) V = Obj->get(Field); @@ -341,6 +347,15 @@ namespace OpenWifi::RESTAPI_utils { Obj.set(Field, Value); } + inline void field_to_json(Poco::JSON::Object &Obj, const char *Field, int64_t Value) { + Obj.set(Field, Value); + } + + inline void field_to_json(Poco::JSON::Object &Obj, const char *Field, uint Value) { + Obj.set(Field, Value); + } + + template void field_to_json(Poco::JSON::Object &Obj, const char *Field, const T &Value) { Poco::JSON::Object Answer; Value.to_json(Answer); @@ -365,6 +380,12 @@ namespace OpenWifi::RESTAPI_utils { } } + inline void field_from_json(const Poco::JSON::Object::Ptr &Obj, const char *Field, int64_t &Value) { + if(Obj->isObject(Field)) { + Value = Obj->get(Field); + } + } + template void field_from_json(const Poco::JSON::Object::Ptr &Obj, const char *Field, T &Value) { if(Obj->isObject(Field)) { Poco::JSON::Object::Ptr A = Obj->getObject(Field); @@ -656,6 +677,23 @@ namespace OpenWifi::Utils { return buf; } + inline uint64_t MACToInt(const std::string &MAC) { + uint64_t Result = 0 ; + for(const auto &c:MAC) { + if(c==':') + continue; + Result <<= 4; + if(c>='0' && c<='9') { + Result += (c - '0'); + } else if (c>='a' && c<='f') { + Result += (c-'a'+10); + } else if (c>='A' && c<='F') { + Result += (c-'A'+10); + } + } + return Result; + } + [[nodiscard]] inline std::string ToHex(const std::vector & B) { std::string R; R.reserve(B.size()*2); @@ -915,13 +953,11 @@ namespace OpenWifi::Utils { [[nodiscard]] inline bool ValidEMailAddress(const std::string &email) { // define a regular expression static const std::regex pattern - (("(\\w+)(\\.|_\\+)?(\\w*)@(\\w+)(\\.(\\w+))+")); - + (("(\\w+)(\\.|_|\\++)?(\\w*)@(\\w+)(\\.(\\w+))+")); // try to match the string with the regular expression return std::regex_match(email, pattern); } - [[nodiscard]] inline std::string LoadFile( const Poco::File & F) { std::string Result; try { @@ -1321,6 +1357,22 @@ namespace OpenWifi { } } + [[nodiscard]] inline Poco::Net::ServerSocket CreateSocket(Poco::Logger &L) const { + Poco::Net::Context::Params P; + + if (address_ == "*") { + Poco::Net::IPAddress Addr(Poco::Net::IPAddress::wildcard( + Poco::Net::Socket::supportsIPv6() ? Poco::Net::AddressFamily::IPv6 + : Poco::Net::AddressFamily::IPv4)); + Poco::Net::SocketAddress SockAddr(Addr, port_); + return Poco::Net::ServerSocket(SockAddr, backlog_); + } else { + Poco::Net::IPAddress Addr(address_); + Poco::Net::SocketAddress SockAddr(Addr, port_); + return Poco::Net::ServerSocket(SockAddr, backlog_); + } + } + inline void LogCertInfo(Poco::Logger &L, const Poco::Crypto::X509Certificate &C) const { L.information("============================================================================================="); L.information(Poco::format("> Issuer: %s", C.issuerName())); @@ -1809,14 +1861,14 @@ namespace OpenWifi { return std::stoull(Hint->second); } - [[nodiscard]] inline bool GetBoolParameter(const std::string &Name, bool Default) { + [[nodiscard]] inline bool GetBoolParameter(const std::string &Name, bool Default=false) { auto Hint = std::find_if(begin(Parameters_),end(Parameters_),[Name](const std::pair &S){ return S.first==Name; }); if(Hint==end(Parameters_) || !is_bool(Hint->second)) return Default; return Hint->second=="true"; } - [[nodiscard]] inline std::string GetParameter(const std::string &Name, const std::string &Default) { + [[nodiscard]] inline std::string GetParameter(const std::string &Name, const std::string &Default="") { auto Hint = std::find_if(begin(Parameters_),end(Parameters_),[Name](const std::pair &S){ return S.first==Name; }); if(Hint==end(Parameters_)) return Default; @@ -2834,33 +2886,6 @@ namespace OpenWifi { RESTAPI_GenericServer &Server_; }; - inline int RESTAPI_ExtServer::Start() { - Server_.InitLogging(); - - for(const auto & Svr: ConfigServersList_) { - Logger().information(Poco::format("Starting: %s:%s Keyfile:%s CertFile: %s", Svr.Address(), std::to_string(Svr.Port()), - Svr.KeyFile(),Svr.CertFile())); - - auto Sock{Svr.CreateSecureSocket(Logger())}; - - Svr.LogCert(Logger()); - if(!Svr.RootCA().empty()) - Svr.LogCas(Logger()); - - Poco::Net::HTTPServerParams::Ptr Params = new Poco::Net::HTTPServerParams; - Params->setMaxThreads(50); - Params->setMaxQueued(200); - Params->setKeepAlive(true); - - auto NewServer = std::make_unique(new ExtRequestHandlerFactory(Server_), Pool_, Sock, Params); - NewServer->start(); - RESTServers_.push_back(std::move(NewServer)); - } - - return 0; - } - - class LogMuxer : public Poco::Channel { public: @@ -2992,32 +3017,6 @@ namespace OpenWifi { RESTAPI_GenericServer &Server_; }; - inline int RESTAPI_IntServer::Start() { - Logger().information("Starting."); - Server_.InitLogging(); - - for(const auto & Svr: ConfigServersList_) { - Logger().information(Poco::format("Starting: %s:%s Keyfile:%s CertFile: %s", Svr.Address(), std::to_string(Svr.Port()), - Svr.KeyFile(),Svr.CertFile())); - - auto Sock{Svr.CreateSecureSocket(Logger())}; - - Svr.LogCert(Logger()); - if(!Svr.RootCA().empty()) - Svr.LogCas(Logger()); - auto Params = new Poco::Net::HTTPServerParams; - Params->setMaxThreads(50); - Params->setMaxQueued(200); - Params->setKeepAlive(true); - - auto NewServer = std::make_unique(new IntRequestHandlerFactory(Server_), Pool_, Sock, Params); - NewServer->start(); - RESTServers_.push_back(std::move(NewServer)); - } - - return 0; - } - struct MicroServiceMeta { uint64_t Id=0; std::string Type; @@ -3052,7 +3051,7 @@ namespace OpenWifi { } [[nodiscard]] std::string Version() { return Version_; } - [[nodiscard]] const Poco::SharedPtr & Key() { return AppKey_; } + // [[nodiscard]] const Poco::SharedPtr & Key() { return AppKey_; } [[nodiscard]] inline const std::string & DataDir() { return DataDir_; } [[nodiscard]] inline const std::string & WWWAssetsDir() { return WWWAssetsDir_; } [[nodiscard]] bool Debug() const { return DebugMode_; } @@ -3142,6 +3141,14 @@ namespace OpenWifi { } } + } + inline bool NoAPISecurity() const { return NoAPISecurity_; } + [[nodiscard]] inline std::string Sign(Poco::JWT::Token &T, const std::string &Algo) { + if(NoBuiltInCrypto_) { + return T.toString(); + } else { + return Signer_.sign(T,Algo); + } } private: static MicroService * instance_; @@ -3168,12 +3175,15 @@ namespace OpenWifi { std::recursive_mutex InfraMutex_; std::default_random_engine RandomEngine_; Poco::Util::PropertyFileConfiguration * PropConfigurationFile_ = nullptr; - std::string DAEMON_PROPERTIES_FILENAME; - std::string DAEMON_ROOT_ENV_VAR; - std::string DAEMON_CONFIG_ENV_VAR; - std::string DAEMON_APP_NAME; - uint64_t DAEMON_BUS_TIMER; - }; + std::string DAEMON_PROPERTIES_FILENAME; + std::string DAEMON_ROOT_ENV_VAR; + std::string DAEMON_CONFIG_ENV_VAR; + std::string DAEMON_APP_NAME; + uint64_t DAEMON_BUS_TIMER; + bool NoAPISecurity_=false; + bool NoBuiltInCrypto_=false; + Poco::JWT::Signer Signer_; + }; inline void MicroService::Exit(int Reason) { std::exit(Reason); @@ -3296,10 +3306,19 @@ namespace OpenWifi { } inline void MicroService::LoadMyConfig() { - std::string KeyFile = ConfigPath("openwifi.service.key"); - std::string KeyFilePassword = ConfigPath("openwifi.service.key.password" , "" ); - AppKey_ = Poco::SharedPtr(new Poco::Crypto::RSAKey("", KeyFile, KeyFilePassword)); - Cipher_ = CipherFactory_.createCipher(*AppKey_); + NoAPISecurity_ = ConfigGetBool("openwifi.security.restapi.disable",false); + std::string KeyFile = ConfigPath("openwifi.service.key",""); + if(!KeyFile.empty()) { + std::string KeyFilePassword = ConfigPath("openwifi.service.key.password", ""); + AppKey_ = Poco::SharedPtr(new Poco::Crypto::RSAKey("", KeyFile, KeyFilePassword)); + Cipher_ = CipherFactory_.createCipher(*AppKey_); + Signer_.setRSAKey(AppKey_); + Signer_.addAllAlgorithms(); + NoBuiltInCrypto_ = false; + } else { + NoBuiltInCrypto_ = true; + } + ID_ = Utils::GetSystemId(); if(!DebugMode_) DebugMode_ = ConfigGetBool("openwifi.system.debug",false); @@ -3629,10 +3648,14 @@ namespace OpenWifi { } inline std::string MicroService::Encrypt(const std::string &S) { + if(NoBuiltInCrypto_) + return S; return Cipher_->encryptString(S, Poco::Crypto::Cipher::Cipher::ENC_BASE64);; } inline std::string MicroService::Decrypt(const std::string &S) { + if(NoBuiltInCrypto_) + return S; return Cipher_->decryptString(S, Poco::Crypto::Cipher::Cipher::ENC_BASE64);; } @@ -3684,7 +3707,68 @@ namespace OpenWifi { SubSystemConfigPrefix_(std::move(SubSystemConfigPrefix)) { } - inline int MicroService::main(const ArgVec &args) { + inline int RESTAPI_ExtServer::Start() { + Server_.InitLogging(); + + for(const auto & Svr: ConfigServersList_) { + Logger().information(Poco::format("Starting: %s:%s Keyfile:%s CertFile: %s", Svr.Address(), std::to_string(Svr.Port()), + Svr.KeyFile(),Svr.CertFile())); + + auto Sock{ MicroService::instance().NoAPISecurity() ? Svr.CreateSocket(Logger()) : Svr.CreateSecureSocket(Logger())}; + + if(MicroService::instance().NoAPISecurity()) { + Logger().information("Security has been disabled for APIs."); + } else { + Svr.LogCert(Logger()); + if (!Svr.RootCA().empty()) + Svr.LogCas(Logger()); + } + + Poco::Net::HTTPServerParams::Ptr Params = new Poco::Net::HTTPServerParams; + Params->setMaxThreads(50); + Params->setMaxQueued(200); + Params->setKeepAlive(true); + + auto NewServer = std::make_unique(new ExtRequestHandlerFactory(Server_), Pool_, Sock, Params); + NewServer->start(); + RESTServers_.push_back(std::move(NewServer)); + } + + return 0; + } + + inline int RESTAPI_IntServer::Start() { + Logger().information("Starting."); + Server_.InitLogging(); + + for(const auto & Svr: ConfigServersList_) { + Logger().information(Poco::format("Starting: %s:%s Keyfile:%s CertFile: %s", Svr.Address(), std::to_string(Svr.Port()), + Svr.KeyFile(),Svr.CertFile())); + + auto Sock{ MicroService::instance().NoAPISecurity() ? Svr.CreateSocket(Logger()) : Svr.CreateSecureSocket(Logger())}; + + if(MicroService::instance().NoAPISecurity()) { + Logger().information("Security has been disabled for APIs."); + } else { + Svr.LogCert(Logger()); + if (!Svr.RootCA().empty()) + Svr.LogCas(Logger()); + } + + auto Params = new Poco::Net::HTTPServerParams; + Params->setMaxThreads(50); + Params->setMaxQueued(200); + Params->setKeepAlive(true); + + auto NewServer = std::make_unique(new IntRequestHandlerFactory(Server_), Pool_, Sock, Params); + NewServer->start(); + RESTServers_.push_back(std::move(NewServer)); + } + + return 0; + } + + inline int MicroService::main(const ArgVec &args) { MyErrorHandler ErrorHandler(*this); Poco::ErrorHandler::set(&ErrorHandler); diff --git a/src/framework/orm.h b/src/framework/orm.h index 3f48e1a..4ffa5b5 100644 --- a/src/framework/orm.h +++ b/src/framework/orm.h @@ -667,9 +667,6 @@ namespace ORM { if(!ItemList.empty()) { OrderByString = " ORDER BY " + ItemList; } - - std::cout << OrderByString << std::endl; - return true; }