From 8ff25257cab08897f1cf5f17b2ef86f05ccd6d7d Mon Sep 17 00:00:00 2001 From: stephb9959 Date: Wed, 27 Oct 2021 10:51:09 -0700 Subject: [PATCH] Simplified token generation. --- build | 2 +- src/AuthService.cpp | 16 +++++++++++----- src/AuthService.h | 24 +++++++++++++++++++++++- src/framework/MicroService.h | 24 ++++++++++++++++++++++-- 4 files changed, 57 insertions(+), 9 deletions(-) diff --git a/build b/build index bf0d87a..62f9457 100644 --- a/build +++ b/build @@ -1 +1 @@ -4 \ No newline at end of file +6 \ No newline at end of file diff --git a/src/AuthService.cpp b/src/AuthService.cpp index cc5e6f6..99dac55 100644 --- a/src/AuthService.cpp +++ b/src/AuthService.cpp @@ -141,7 +141,13 @@ namespace OpenWifi { } } - std::string AuthService::GenerateToken(const std::string & Identity, ACCESS_TYPE Type) { + [[nodiscard]] std::string AuthService::GenerateTokenHMAC(const std::string & UserName, ACCESS_TYPE Type) { + std::string Identity(UserName + ":" + Poco::format("%d",(int)std::time(nullptr))); + HMAC_.update(Identity); + return Poco::DigestEngine::digestToHex(HMAC_.digest()); + } + + std::string AuthService::GenerateTokenJWT(const std::string & Identity, ACCESS_TYPE Type) { std::lock_guard Guard(Mutex_); Poco::JWT::Token T; @@ -163,7 +169,6 @@ namespace OpenWifi { bool AuthService::ValidateToken(const std::string & Token, std::string & SessionToken, SecurityObjects::UserInfoAndPolicy & UInfo ) { std::lock_guard Guard(Mutex_); - Poco::JWT::Token DecryptedToken; try { auto E = UserCache_.find(SessionToken); @@ -194,9 +199,9 @@ namespace OpenWifi { UInfo.webtoken.expires_in_ = TokenAging_ ; UInfo.webtoken.idle_timeout_ = 5 * 60; UInfo.webtoken.token_type_ = "Bearer"; - UInfo.webtoken.access_token_ = GenerateToken(UInfo.userinfo.Id,USERNAME); - UInfo.webtoken.id_token_ = GenerateToken(UInfo.userinfo.Id,USERNAME); - UInfo.webtoken.refresh_token_ = GenerateToken(UInfo.userinfo.Id,CUSTOM); + UInfo.webtoken.access_token_ = GenerateTokenHMAC(UInfo.userinfo.Id,USERNAME); + UInfo.webtoken.id_token_ = GenerateTokenHMAC(UInfo.userinfo.Id,USERNAME); + UInfo.webtoken.refresh_token_ = GenerateTokenHMAC(UInfo.userinfo.Id,CUSTOM); UInfo.webtoken.created_ = time(nullptr); UInfo.webtoken.username_ = UserName; UInfo.webtoken.errorCode = 0; @@ -274,6 +279,7 @@ namespace OpenWifi { UInfo.userinfo.email = DefaultUserName_; UInfo.userinfo.currentPassword = DefaultPassword_; UInfo.userinfo.name = DefaultUserName_; + UInfo.userinfo.userRole = SecurityObjects::ROOT; CreateToken(UserName, UInfo ); return SUCCESS; } diff --git a/src/AuthService.h b/src/AuthService.h index da3e11b..a35fdd3 100644 --- a/src/AuthService.h +++ b/src/AuthService.h @@ -16,6 +16,8 @@ #include "Poco/Net/HTTPServerResponse.h" #include "Poco/JWT/Signer.h" #include "Poco/SHA2Engine.h" +#include "Poco/Crypto/DigestEngine.h" +#include "Poco/HMACEngine.h" #include "framework/MicroService.h" #include "RESTObjects/RESTAPI_SecurityObjects.h" @@ -73,7 +75,8 @@ namespace OpenWifi{ [[nodiscard]] bool IsValidToken(const std::string &Token, SecurityObjects::WebToken &WebToken, SecurityObjects::UserInfo &UserInfo); [[nodiscard]] bool IsValidAPIKEY(const Poco::Net::HTTPServerRequest &Request); - [[nodiscard]] std::string GenerateToken(const std::string & UserName, ACCESS_TYPE Type); + [[nodiscard]] std::string GenerateTokenJWT(const std::string & UserName, ACCESS_TYPE Type); + [[nodiscard]] std::string GenerateTokenHMAC(const std::string & UserName, ACCESS_TYPE Type); [[nodiscard]] bool ValidateToken(const std::string & Token, std::string & SessionToken, SecurityObjects::WebToken & UserInfo ); [[nodiscard]] std::string ComputePasswordHash(const std::string &UserName, const std::string &Password); [[nodiscard]] bool UpdatePassword(const std::string &Admin, const std::string &UserName, const std::string & OldPassword, const std::string &NewPassword); @@ -97,6 +100,25 @@ namespace OpenWifi{ std::regex PasswordValidation_; uint64_t TokenAging_ = 30 * 24 * 60 * 60; uint64_t HowManyOldPassword_=5; + + class SHA256Engine : public Poco::Crypto::DigestEngine + { + public: + enum + { + BLOCK_SIZE = 64, + DIGEST_SIZE = 32 + }; + + SHA256Engine() + : DigestEngine("SHA256") + { + } + + }; + + Poco::HMACEngine HMAC_{"tipopenwifi"}; + AuthService() noexcept: SubSystemServer("Authentication", "AUTH-SVR", "authentication") { diff --git a/src/framework/MicroService.h b/src/framework/MicroService.h index b144c37..0a64511 100644 --- a/src/framework/MicroService.h +++ b/src/framework/MicroService.h @@ -1262,6 +1262,10 @@ namespace OpenWifi { RESTAPIHandler(BindingMap map, Poco::Logger &l, std::vector Methods, RESTAPI_GenericServer & Server, bool Internal=false, bool AlwaysAuthorize=true) : Bindings_(std::move(map)), Logger_(l), Methods_(std::move(Methods)), Server_(Server), Internal_(Internal), AlwaysAuthorize_(AlwaysAuthorize) {} + inline bool RoleIsAuthorized(std::string & Reason) { + return true; + } + inline void handleRequest(Poco::Net::HTTPServerRequest &RequestIn, Poco::Net::HTTPServerResponse &ResponseIn) final { try { @@ -1271,8 +1275,15 @@ namespace OpenWifi { if (!ContinueProcessing()) return; - if (AlwaysAuthorize_ && !IsAuthorized()) + if (AlwaysAuthorize_ && !IsAuthorized()) { return; + } + + std::string Reason; + if(!RoleIsAuthorized(Reason)) { + UnAuthorized(Reason); + return; + } ParseParameters(); if (Request->getMethod() == Poco::Net::HTTPRequest::HTTP_GET) @@ -3084,7 +3095,16 @@ namespace OpenWifi { Internal) {} static const std::list PathName() { return std::list{"/api/v1/system"};} - inline void DoGet() { + bool RoleIsAuthorized(std::string & Reason) { + if( UserInfo_.userinfo.userRole != SecurityObjects::USER_ROLE::ROOT && + UserInfo_.userinfo.userRole != SecurityObjects::USER_ROLE::ADMIN ) { + Reason = "User must be ADMIN/ROOT to perform this operation."; + return false; + } + return true; + } + + inline void DoGet() { std::string Arg; if(HasParameter("command",Arg) && Arg=="info") { Poco::JSON::Object Answer;