Provide better LOG function, refactor cmake
This commit is contained in:
parent
5ad212cd62
commit
3cb8567f42
@ -8,11 +8,11 @@ add_library(rublon-ssh
|
||||
include/rublon/curl.hpp
|
||||
include/rublon/span.hpp
|
||||
include/rublon/sign.hpp
|
||||
include/rublon/utils.hpp
|
||||
include/rublon/CoreHandler.hpp
|
||||
include/rublon/configuration.hpp
|
||||
)
|
||||
|
||||
#set(CMAKE_SHARED_LINKER_FLAGS "-fpic -static-libstdc++ -fvisibility=hidden -ffunction-sections -fdata-sections -fwhole-program")
|
||||
|
||||
target_include_directories(rublon-ssh
|
||||
PUBLIC INTERFACE
|
||||
|
||||
@ -27,7 +27,7 @@ template < typename Impl >
|
||||
class CoreHandlerInterface {
|
||||
public:
|
||||
tl::expected< rublon::Document, CoreHandlerError > request(std::string_view path, const rublon::Document & body) const {
|
||||
rublon::debugLog("[TMP] request",__PRETTY_FUNCTION__);
|
||||
rublon::log(LogLevel::Debug, "%s", __PRETTY_FUNCTION__);
|
||||
return static_cast< const Impl * >(this)->request(path, body);
|
||||
}
|
||||
};
|
||||
@ -42,12 +42,10 @@ class CoreHandler : public CoreHandlerInterface< CoreHandler< HttpHandler > > {
|
||||
}
|
||||
|
||||
void signRequest(std::pmr::monotonic_buffer_resource & mr, Request & request) const {
|
||||
rublon::debugLog("[TMP]",__PRETTY_FUNCTION__);
|
||||
request.headers["X-Rublon-Signature"] = xRublonSignature(mr, request.body);
|
||||
}
|
||||
|
||||
bool responseSigned(const Response & response) const {
|
||||
rublon::debugLog("[TMP]",__PRETTY_FUNCTION__);
|
||||
const auto & xRubResp = response.headers.at("x-rublon-signature");
|
||||
const auto & sign = signData(response.body, secretKey);
|
||||
return xRubResp == sign.data();
|
||||
@ -62,7 +60,7 @@ class CoreHandler : public CoreHandlerInterface< CoreHandler< HttpHandler > > {
|
||||
CoreHandler(const rublon::Configuration & config) : secretKey{config.parameters.secretKey}, url{config.parameters.apiServer} {}
|
||||
|
||||
tl::expected< rublon::Document, CoreHandlerError > request(std::string_view path, const rublon::Document & body) const {
|
||||
rublon::debugLog("[TMP] request",__PRETTY_FUNCTION__);
|
||||
rublon::log(LogLevel::Info, "Sending request to %s", path.data());
|
||||
|
||||
std::byte _buffer[16 * 1024];
|
||||
std::pmr::monotonic_buffer_resource mr{_buffer, sizeof(_buffer)};
|
||||
@ -79,32 +77,30 @@ class CoreHandler : public CoreHandlerInterface< CoreHandler< HttpHandler > > {
|
||||
|
||||
request.body = jsonStr.GetString();
|
||||
|
||||
rublon::debugLog("[TMP] request", "sign");
|
||||
signRequest(mr, request);
|
||||
|
||||
// std::pmr::string uri{url + path.data(), &mr};
|
||||
std::pmr::string uri{url + path.data(), &mr};
|
||||
|
||||
// rublon::debugLog("[TMP] send", request.body.c_str());
|
||||
// auto response = http.request(uri, request);
|
||||
auto response = http.request(uri, request);
|
||||
|
||||
// if(not response.has_value()) {
|
||||
if(not response.has_value()) {
|
||||
return tl::unexpected{CoreHandlerError::ConnectionError};
|
||||
// }
|
||||
// if(not responseSigned(*response)) {
|
||||
// return tl::unexpected{CoreHandlerError::BadSigature};
|
||||
// }
|
||||
}
|
||||
if(not responseSigned(*response)) {
|
||||
return tl::unexpected{CoreHandlerError::BadSigature};
|
||||
}
|
||||
|
||||
// rublon::Document resp{&alloc};
|
||||
// resp.Parse(response->body.c_str());
|
||||
rublon::Document resp{&alloc};
|
||||
resp.Parse(response->body.c_str());
|
||||
|
||||
// if(resp.HasParseError() or not resp.HasMember("result")) {
|
||||
// return tl::unexpected{CoreHandlerError::BrokenData};
|
||||
// }
|
||||
// if(resp["result"].HasMember("exception")) {
|
||||
// return tl::unexpected{CoreHandlerError{CoreHandlerError::CoreException, resp["result"]["exception"].GetString()}};
|
||||
// }
|
||||
if(resp.HasParseError() or not resp.HasMember("result")) {
|
||||
return tl::unexpected{CoreHandlerError::BrokenData};
|
||||
}
|
||||
if(resp["result"].HasMember("exception")) {
|
||||
return tl::unexpected{CoreHandlerError{CoreHandlerError::CoreException, resp["result"]["exception"].GetString()}};
|
||||
}
|
||||
|
||||
// return resp;
|
||||
return resp;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@ -15,41 +15,37 @@
|
||||
|
||||
namespace rublon {
|
||||
static size_t WriteMemoryCallback(void * contents, size_t size, size_t nmemb, void * userp) {
|
||||
size_t realsize = size * nmemb;
|
||||
size_t realsize = size * nmemb;
|
||||
reinterpret_cast< std::string * >(userp)->append(static_cast< const char * >(contents), realsize);
|
||||
return realsize;
|
||||
}
|
||||
|
||||
struct Request{
|
||||
std::map<std::string, std::string> headers;
|
||||
struct Request {
|
||||
std::map< std::string, std::string > headers;
|
||||
std::string body;
|
||||
};
|
||||
|
||||
struct Response{
|
||||
std::map<std::string, std::string> headers;
|
||||
struct Response {
|
||||
std::map< std::string, std::string > headers;
|
||||
std::string body;
|
||||
};
|
||||
|
||||
|
||||
class CURL {
|
||||
std::unique_ptr< ::CURL, void (*)(::CURL *) > curl;
|
||||
|
||||
public:
|
||||
CURL() : curl{std::unique_ptr< ::CURL, void (*)(::CURL *) >(curl_easy_init(), curl_easy_cleanup)} {}
|
||||
|
||||
std::optional< Response > request(std::string_view uri, const Request &request) const {
|
||||
rublon::debugLog("[TMP] request",__PRETTY_FUNCTION__);
|
||||
|
||||
std::optional< Response > request(std::string_view uri, const Request & request) const {
|
||||
std::string response_data;
|
||||
response_data.reserve(1000);
|
||||
|
||||
|
||||
|
||||
Response response;
|
||||
|
||||
/// TODO this can be done on stack using pmr
|
||||
auto curl_headers = std::unique_ptr< curl_slist, void (*)(curl_slist *) >(nullptr, curl_slist_free_all);
|
||||
std::for_each(request.headers.begin(), request.headers.end(), [&](auto header) {
|
||||
curl_headers.reset(curl_slist_append(curl_headers.release(),(header.first + ": " + header.second).c_str()));
|
||||
curl_headers.reset(curl_slist_append(curl_headers.release(), (header.first + ": " + header.second).c_str()));
|
||||
});
|
||||
|
||||
curl_easy_setopt(curl.get(), CURLOPT_VERBOSE, 1);
|
||||
@ -61,21 +57,20 @@ class CURL {
|
||||
curl_easy_setopt(curl.get(), CURLOPT_HEADER, 1);
|
||||
curl_easy_setopt(curl.get(), CURLOPT_WRITEFUNCTION, WriteMemoryCallback);
|
||||
curl_easy_setopt(curl.get(), CURLOPT_WRITEDATA, &response_data);
|
||||
|
||||
rublon::debugLog("[TMP] calling curl",__PRETTY_FUNCTION__);
|
||||
|
||||
|
||||
rublon::log(LogLevel::Debug, "Request send uri:{%s} body:{%s}", uri.data(), request.body.c_str());
|
||||
auto res = curl_easy_perform(curl.get());
|
||||
if(res != CURLE_OK) {
|
||||
// debugLog("No response from Rublon server (perform)", "");
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
|
||||
long size;
|
||||
curl_easy_getinfo(curl.get(), CURLINFO_HEADER_SIZE, &size);
|
||||
|
||||
///TODO ogarnąć alokację pamięci
|
||||
response.headers = details::headers({response_data.data(), static_cast<std::size_t>(size)});
|
||||
response.body = response_data.substr(size);
|
||||
|
||||
/// TODO ogarnąć alokację pamięci
|
||||
response.headers = details::headers({response_data.data(), static_cast< std::size_t >(size)});
|
||||
response.body = response_data.substr(size);
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
@ -35,7 +35,6 @@ class MethodFactory {
|
||||
|
||||
template < typename Array_t >
|
||||
tl::expected< Method, PamAction > create(const Array_t & methods) const {
|
||||
rublon::debugLog("[TMP] ",__PRETTY_FUNCTION__);
|
||||
std::pmr::map< int, std::pmr::string > methods_id;
|
||||
pam.print("%s", "");
|
||||
int i;
|
||||
|
||||
@ -23,22 +23,24 @@ class LinuxPam {
|
||||
|
||||
public:
|
||||
LinuxPam(pam_handle_t * handler) : pamh{handler} {}
|
||||
|
||||
|
||||
rublon::NonOwningPtr< const char > ip() const {
|
||||
const void * ip = NULL;
|
||||
pam_get_item(pamh, PAM_RHOST, &ip);
|
||||
if(ip == NULL)
|
||||
if(ip == NULL) {
|
||||
rublon::log(rublon::LogLevel::Warning, "Cant read user from linux PAM");
|
||||
ip = "";
|
||||
rublon::debugLog(__PRETTY_FUNCTION__, (const char*)ip);
|
||||
return (const char*)ip;
|
||||
}
|
||||
return ( const char * ) ip;
|
||||
}
|
||||
|
||||
rublon::NonOwningPtr< const char > username() const {
|
||||
const char * user = NULL;
|
||||
pam_get_user(pamh, &user, nullptr);
|
||||
if(user == NULL)
|
||||
if(user == NULL) {
|
||||
rublon::log(rublon::LogLevel::Warning, "Cant read user from linux PAM");
|
||||
user = "";
|
||||
rublon::debugLog(__PRETTY_FUNCTION__, user);
|
||||
}
|
||||
return user;
|
||||
}
|
||||
|
||||
@ -50,7 +52,7 @@ class LinuxPam {
|
||||
template < typename Fun, typename... Ti >
|
||||
[[nodiscard]] auto scan(Fun && f, const char * fmt, Ti... ti) const noexcept {
|
||||
char * responseBuffer = nullptr;
|
||||
pam_prompt(pamh, PAM_PROMPT_ECHO_ON, &responseBuffer, fmt, std::forward< Ti... >(ti...));
|
||||
pam_prompt(pamh, PAM_PROMPT_ECHO_ON, &responseBuffer, fmt, std::forward< Ti... >(ti...));
|
||||
if(responseBuffer) {
|
||||
auto ret = f(responseBuffer);
|
||||
free(responseBuffer);
|
||||
|
||||
@ -62,13 +62,11 @@ class Init : public AuthenticationStep< Init< MethodFactory_t, PamInfo_t > > {
|
||||
|
||||
Init(pam_handle_t * pamHandler, const rublon::Configuration & config)
|
||||
: _systemToken{config.parameters.systemToken}, _pamInfo{pamHandler}, _methodFactory{_pamInfo} {
|
||||
rublon::debugLog("[TMP] Init ctor",__PRETTY_FUNCTION__);
|
||||
}
|
||||
|
||||
/// TODO add core handler interface
|
||||
template < typename Hander_t >
|
||||
tl::expected< Method, PamAction > handle(const CoreHandlerInterface< Hander_t > & coreHandler) const {
|
||||
rublon::debugLog("[TMP] init handle",__PRETTY_FUNCTION__);
|
||||
char _buffer[1024];
|
||||
std::pmr::monotonic_buffer_resource mr{_buffer, 1024};
|
||||
|
||||
@ -85,7 +83,7 @@ class Init : public AuthenticationStep< Init< MethodFactory_t, PamInfo_t > > {
|
||||
params.AddMember("os", "Ubuntu 23.04", alloc); /// TODO add version to cmake
|
||||
|
||||
body.AddMember("params", std::move(params), alloc);
|
||||
rublon::debugLog("[TMP] calling coreHandler",__PRETTY_FUNCTION__);
|
||||
|
||||
auto httpResponse = coreHandler.request(apiPath, body);
|
||||
|
||||
// if(httpResponse.has_value()) {
|
||||
|
||||
@ -1,9 +1,11 @@
|
||||
#pragma once
|
||||
|
||||
#include <algorithm>
|
||||
#include <array>
|
||||
#include <cctype>
|
||||
#include <cstring>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <memory_resource>
|
||||
#include <sstream>
|
||||
#include <string_view>
|
||||
@ -16,19 +18,49 @@
|
||||
#include <syslog.h>
|
||||
|
||||
namespace rublon {
|
||||
enum LogLevel { Debug, Info, Warning, Error };
|
||||
|
||||
inline void debugLog(const char * message1, const char * message2) {
|
||||
auto file_name = "/tmp/rublon.log";
|
||||
auto fp = fopen(file_name, "a");
|
||||
fprintf(fp, "[%s] %s %s\n", "cmake version", message1, message2);
|
||||
fflush(fp);
|
||||
fclose(fp);
|
||||
|
||||
// openlog("pam_rublon", LOG_CONS | LOG_PID | LOG_NDELAY, LOG_LOCAL1);
|
||||
// syslog(LOG_NOTICE, "[%s] %s %s", "cmake version", message1, message2);
|
||||
// closelog();
|
||||
namespace {
|
||||
inline auto dateStr() {
|
||||
std::array< char, 32 > date;
|
||||
time_t now;
|
||||
time(&now);
|
||||
strftime(date.data(), date.size(), "%FT%TZ", gmtime(&now));
|
||||
return date;
|
||||
}
|
||||
|
||||
const auto LogLevelNames = {"Debug", "Info", "Warning", "Error"};
|
||||
|
||||
template < typename... Ti >
|
||||
void log(LogLevel level, const char * fmt, Ti &&... ti) noexcept {
|
||||
constexpr auto file_name = "/var/log/rublon-ssh.log";
|
||||
|
||||
if(level < 0)
|
||||
return;
|
||||
|
||||
auto fp = std::unique_ptr< FILE, int (*)(FILE *) >(fopen(file_name, "a"), fclose);
|
||||
|
||||
if(fp) {
|
||||
std::array< char, 1000 > line;
|
||||
|
||||
sprintf(line.data(), fmt, std::forward< Ti >(ti)...);
|
||||
|
||||
fprintf(fp.get(), "[%s] %s %s\n", "rublon_ssh_pam", dateStr().data(), line.data());
|
||||
}
|
||||
}
|
||||
}
|
||||
// inline void debugLog(const char * message1, const char * message2) {
|
||||
// auto file_name = "/tmp/rublon.log";
|
||||
// auto fp = fopen(file_name, "a");
|
||||
// fprintf(fp, "[%s] %s %s\n", "cmake version", message1, message2);
|
||||
// fflush(fp);
|
||||
// fclose(fp);
|
||||
|
||||
//// openlog("pam_rublon", LOG_CONS | LOG_PID | LOG_NDELAY, LOG_LOCAL1);
|
||||
//// syslog(LOG_NOTICE, "[%s] %s %s", "cmake version", message1, message2);
|
||||
//// closelog();
|
||||
//}
|
||||
|
||||
template < typename T >
|
||||
class NonOwningPtr {
|
||||
T * object;
|
||||
|
||||
@ -3,12 +3,29 @@ add_library(rublon-ssh-pam
|
||||
pam.cpp
|
||||
)
|
||||
|
||||
target_compile_options(rublon-ssh-pam
|
||||
PUBLIC
|
||||
-fno-exceptions
|
||||
-fno-rtti
|
||||
-fvisibility=hidden
|
||||
-ffunction-sections
|
||||
-fdata-sections
|
||||
-fno-unwind-tables
|
||||
-fno-asynchronous-unwind-tables
|
||||
)
|
||||
|
||||
target_link_options(rublon-ssh-pam
|
||||
PUBLIC
|
||||
-fpic -shared
|
||||
-fpic
|
||||
-s
|
||||
# -static-libstdc++
|
||||
-Wl,--gc-sections
|
||||
)
|
||||
|
||||
target_link_libraries(rublon-ssh-pam
|
||||
PUBLIC
|
||||
-lcurl -lssl -lcrypto rublon-ssh
|
||||
rublon-ssh
|
||||
-lcurl
|
||||
-lssl
|
||||
-lcrypto
|
||||
)
|
||||
|
||||
@ -9,6 +9,8 @@
|
||||
#include <rublon/rublon.hpp>
|
||||
#include <rublon/utils.hpp>
|
||||
|
||||
#define DLL_PUBLIC __attribute__ ((visibility ("default")))
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace {
|
||||
@ -22,30 +24,21 @@ Expected< rublon::Confirm > confirm() {}
|
||||
|
||||
} // namespace
|
||||
|
||||
PAM_EXTERN int pam_sm_setcred(pam_handle_t * pamh, int flags, int argc, const char ** argv) {
|
||||
rublon::debugLog("[TMP]start", __PRETTY_FUNCTION__);
|
||||
|
||||
DLL_PUBLIC int pam_sm_setcred(pam_handle_t * pamh, int flags, int argc, const char ** argv) {
|
||||
return PAM_SUCCESS;
|
||||
}
|
||||
|
||||
PAM_EXTERN int pam_sm_acct_mgmt(pam_handle_t * pamh, int flags, int argc, const char ** argv) {
|
||||
rublon::debugLog("[TMP]start", __PRETTY_FUNCTION__);
|
||||
|
||||
DLL_PUBLIC int pam_sm_acct_mgmt(pam_handle_t * pamh, int flags, int argc, const char ** argv) {
|
||||
return PAM_SUCCESS;
|
||||
}
|
||||
|
||||
PAM_EXTERN int pam_sm_authenticate(pam_handle_t * pamh, int flags, int argc, const char ** argv) {
|
||||
rublon::debugLog("[TMP]start", __PRETTY_FUNCTION__);
|
||||
DLL_PUBLIC int pam_sm_authenticate(pam_handle_t * pamh, int flags, int argc, const char ** argv) {
|
||||
auto rublonConfig = rublon::ConfigurationFactory{}.systemConfig();
|
||||
|
||||
rublon::debugLog("[TMP]create core handler", "");
|
||||
rublon::CoreHandler CH{rublonConfig.value()};
|
||||
|
||||
rublon::debugLog("[TMP]start", "");
|
||||
auto action = rublon::Init{pamh, rublonConfig.value()}
|
||||
.fire(CH) //
|
||||
.and_then([](const auto & method) -> Expected< int > {
|
||||
rublon::debugLog("[TMP]start", "init lambda");
|
||||
return tl::unexpected{rublon::PamAction::accept};
|
||||
});
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user