diff --git a/PAM/ssh/include/rublon/init.hpp b/PAM/ssh/include/rublon/init.hpp index e69de29..72d22b8 100644 --- a/PAM/ssh/include/rublon/init.hpp +++ b/PAM/ssh/include/rublon/init.hpp @@ -0,0 +1,77 @@ +#pragma once + +#include +#include + +#include +#include + +#include + +namespace rublon{ +template < template < typename > class MethodFactory_t = MethodFactory, typename PamInfo_t = LinuxPam > +class Init : public AuthenticationStep< Init< MethodFactory_t, PamInfo_t > > { + const char * apiPath = "/api/transaction/init"; + const std::string & _systemToken; + + protected: + PamInfo_t _pamInfo; + MethodFactory_t< PamInfo_t > _methodFactory; + + public: + const char * name = "Initialization"; + + Init(pam_handle_t * pamHandler, const rublon::Configuration & config) + : _systemToken{config.parameters.systemToken}, _pamInfo{pamHandler}, _methodFactory{_pamInfo} {} + + /// TODO add core handler interface + template < typename Hander_t > + tl::expected< Method, PamAction > handle(const CoreHandlerInterface< Hander_t > & coreHandler) const { + char _buffer[1024]; + std::pmr::monotonic_buffer_resource mr{_buffer, 1024}; + + RapidJSONPMRAlloc alloc{&mr}; + Document body{rapidjson::kObjectType, &alloc}; + + body.AddMember("systemToken", Value{_systemToken.c_str(), alloc}, alloc); + body.AddMember("username", Value{_pamInfo.username().get(), alloc}, alloc); + body.AddMember("userEmail", "bwi@rublon.com", alloc); /// TODO proper username + + Value params{rapidjson::kObjectType}; + params.AddMember("userIP", Value{_pamInfo.ip().get(), alloc}, alloc); + params.AddMember("appVer", "v.1.6", alloc); /// TODO add version to cmake + params.AddMember("os", "Ubuntu 23.04", alloc); /// TODO add version to cmake + + body.AddMember("params", std::move(params), alloc); + + auto httpResponse = coreHandler.request(apiPath, body); + + if(httpResponse.has_value()) { + log(LogLevel::Info, "[TMP] has response, processing", __PRETTY_FUNCTION__); + const auto & rublonResponse = httpResponse.value()["response"]; + + std::string tid = rublonResponse["tid"].GetString(); + + return _methodFactory.create(rublonResponse["methods"].GetArray()); + } else { + // mostly connectio errors + switch(httpResponse.error().errorClass) { + case CoreHandlerError::ErrorClass::BadSigature: + log(LogLevel::Error, "ErrorClass::BadSigature"); + return tl::unexpected{PamAction::decline}; + case CoreHandlerError::ErrorClass::CoreException: /// TODO exception handling + log(LogLevel::Error, "ErrorClass::CoreException"); + return tl::unexpected{PamAction::decline}; /// TODO accept? + case CoreHandlerError::ErrorClass::ConnectionError: + log(LogLevel::Error, "ErrorClass::ConnectionError"); + return tl::unexpected{PamAction::decline}; /// TODO decline? + case CoreHandlerError::ErrorClass::BrokenData: + log(LogLevel::Error, "ErrorClass::BrokenData"); + return tl::unexpected{PamAction::decline}; + } + } + + return tl::unexpected{PamAction::decline}; + } +}; +} diff --git a/PAM/ssh/include/rublon/method/method_factory.hpp b/PAM/ssh/include/rublon/method/method_factory.hpp index 1d5ac3d..a147d7f 100644 --- a/PAM/ssh/include/rublon/method/method_factory.hpp +++ b/PAM/ssh/include/rublon/method/method_factory.hpp @@ -17,10 +17,8 @@ class Method { std::string tid; public: - template - Method(const Method_t &&){ - - } + Method() {} + template < typename Handler_t > tl::expected< int , PamAction > fire(const CoreHandlerInterface< Handler_t > & coreHandler) { return std::visit([&](const auto & method) { return method.fire(coreHandler); }, _impl); @@ -69,6 +67,8 @@ class MethodFactory { pam.print("you selected: %s", methods_id.count(methodid.value_or(0)) ? methods_id.at(methodid.value_or(0)).c_str() : "unknown option"); + + return tl::unexpected{PamAction::accept}; } }; diff --git a/PAM/ssh/include/rublon/rublon.hpp b/PAM/ssh/include/rublon/rublon.hpp index 66bdf22..54829b3 100644 --- a/PAM/ssh/include/rublon/rublon.hpp +++ b/PAM/ssh/include/rublon/rublon.hpp @@ -12,8 +12,7 @@ #include #include -#include "json.hpp" -#include "pam.hpp" + #include #include @@ -28,71 +27,7 @@ class Confirm : public AuthenticationStep< Confirm > { Confirm(const Configuration & /*config*/) {} }; -template < template < typename > class MethodFactory_t = MethodFactory, typename PamInfo_t = LinuxPam > -class Init : public AuthenticationStep< Init< MethodFactory_t, PamInfo_t > > { - const char * apiPath = "/api/transaction/init"; - const std::string & _systemToken; - protected: - PamInfo_t _pamInfo; - MethodFactory_t< PamInfo_t > _methodFactory; - - public: - const char * name = "Initialization"; - - Init(pam_handle_t * pamHandler, const rublon::Configuration & config) - : _systemToken{config.parameters.systemToken}, _pamInfo{pamHandler}, _methodFactory{_pamInfo} {} - - /// TODO add core handler interface - template < typename Hander_t > - tl::expected< Method, PamAction > handle(const CoreHandlerInterface< Hander_t > & coreHandler) const { - char _buffer[1024]; - std::pmr::monotonic_buffer_resource mr{_buffer, 1024}; - - RapidJSONPMRAlloc alloc{&mr}; - Document body{rapidjson::kObjectType, &alloc}; - - body.AddMember("systemToken", Value{_systemToken.c_str(), alloc}, alloc); - body.AddMember("username", Value{_pamInfo.username().get(), alloc}, alloc); - body.AddMember("userEmail", "bwi@rublon.com", alloc); /// TODO proper username - - Value params{rapidjson::kObjectType}; - params.AddMember("userIP", Value{_pamInfo.ip().get(), alloc}, alloc); - params.AddMember("appVer", "v.1.6", alloc); /// TODO add version to cmake - params.AddMember("os", "Ubuntu 23.04", alloc); /// TODO add version to cmake - - body.AddMember("params", std::move(params), alloc); - - auto httpResponse = coreHandler.request(apiPath, body); - - if(httpResponse.has_value()) { - log(LogLevel::Info, "[TMP] has response, processing", __PRETTY_FUNCTION__); - const auto & rublonResponse = httpResponse.value()["response"]; - - std::string tid = rublonResponse["tid"].GetString(); - - return _methodFactory.create(rublonResponse["methods"].GetArray()); - } else { - // mostly connectio errors - switch(httpResponse.error().errorClass) { - case CoreHandlerError::ErrorClass::BadSigature: - log(LogLevel::Error, "ErrorClass::BadSigature"); - return tl::unexpected{PamAction::decline}; - case CoreHandlerError::ErrorClass::CoreException: /// TODO exception handling - log(LogLevel::Error, "ErrorClass::CoreException"); - return tl::unexpected{PamAction::decline}; /// TODO accept? - case CoreHandlerError::ErrorClass::ConnectionError: - log(LogLevel::Error, "ErrorClass::ConnectionError"); - return tl::unexpected{PamAction::decline}; /// TODO decline? - case CoreHandlerError::ErrorClass::BrokenData: - log(LogLevel::Error, "ErrorClass::BrokenData"); - return tl::unexpected{PamAction::decline}; - } - } - - return tl::unexpected{PamAction::decline}; - } -}; class VerifySSH : public AuthenticationStep< VerifySSH > { public: diff --git a/PAM/ssh/lib/pam.cpp b/PAM/ssh/lib/pam.cpp index 02b323b..a00ab85 100644 --- a/PAM/ssh/lib/pam.cpp +++ b/PAM/ssh/lib/pam.cpp @@ -9,6 +9,8 @@ #include #include +#include + #define DLL_PUBLIC __attribute__ ((visibility ("default"))) using namespace std; diff --git a/PAM/ssh/tests/CMakeLists.txt b/PAM/ssh/tests/CMakeLists.txt index 28054e6..d2dd84d 100644 --- a/PAM/ssh/tests/CMakeLists.txt +++ b/PAM/ssh/tests/CMakeLists.txt @@ -20,5 +20,5 @@ FetchContent_MakeAvailable( googletest googlebenchmark) -add_executable(rublon-tests utilsTests.cpp rublonTests.cpp core_handler_tests.cpp init_test.cpp) +add_executable(rublon-tests utilsTests.cpp rublonTests.cpp core_handler_tests.cpp init_test.cpp method_factory_test.cpp) target_link_libraries(rublon-tests rublon-ssh GTest::gmock_main -lssl -lcrypto) diff --git a/PAM/ssh/tests/init_test.cpp b/PAM/ssh/tests/init_test.cpp index 7387d61..886ef60 100644 --- a/PAM/ssh/tests/init_test.cpp +++ b/PAM/ssh/tests/init_test.cpp @@ -1,7 +1,7 @@ #include #include -#include +#include #include "core_response_generator.hpp" diff --git a/PAM/ssh/tests/method_factory_test.cpp b/PAM/ssh/tests/method_factory_test.cpp new file mode 100644 index 0000000..e69de29