Bwi/v2.2.0 (#16)

* Remove dynamic memory usage from core

* Refacor status check to use json pointers

* Move access token to session

* Remove code duplication

* Fix compile warnings from rapidjson sources

* Add 'interactive mode option to session configuration

* Implement non interactive mode connector

* Add 'non interactove' implementation

* Apply rapidjson patch

* Build on all cores

* Rename build script

* Split configure and build steps

* Add scripts for building all images

* Change bash to python for build scripts

* Stop printing methods name in non interactive mode

* Add trace log level, adn more params to init message

* Fix build

* Fix non interactive method selection and refactor vagrant files for debian like systems

* Refactor log messages

* Remove exces dependencies from vagrant configuration files

* Fixed vagrantfiles

* Added repo for rhel

* Add nonInteractiveMode option

* Added instalation script for pubkey

* Fixed pubkey install script and postrm for rhel
This commit is contained in:
rublon-bwi 2025-03-07 11:41:12 +01:00 committed by GitHub
parent 6b9d2f938c
commit af64f8e9e3
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
61 changed files with 976 additions and 726 deletions

1
.gitignore vendored
View File

@ -77,3 +77,4 @@ CMakeLists.txt.user*
# Output files
build/
_tmp/

View File

@ -6,7 +6,7 @@ include(CTest)
include(GNUInstallDirs)
set(PROJECT_VERSION_MAJOR 2)
set(PROJECT_VERSION_MINOR 1)
set(PROJECT_VERSION_MINOR 2)
set(PROJECT_VERSION_PATCH 0)
set(RUBLON_VERSION_STRING "${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_PATCH}")
@ -17,6 +17,9 @@ set(CMAKE_POSITION_INDEPENDENT_CODE YES)
add_compile_options(-Wall -Wextra -Wno-format-security)
# add_compile_options(-g -fsanitize=address,undefined,float-divide-by-zero,float-cast-overflow,null -fsanitize-address-use-after-scope -fno-sanitize-recover=all -fno-sanitize=alignment -fno-omit-frame-pointer)
# add_link_options(-g -fsanitize=address,undefined,float-divide-by-zero,float-cast-overflow,null -fsanitize-address-use-after-scope -fno-sanitize-recover=all -fno-sanitize=alignment -fno-omit-frame-pointer)
add_compile_definitions(RUBLON_VERSION_STRING="${RUBLON_VERSION_STRING}")
option(ENABLE_TESTS "Enable tests" OFF)
@ -25,13 +28,16 @@ add_custom_target(INSTSCRIPTS_IDE SUORCES ${CMAKE_CURRENT_LIST_DIR}/service/help
execute_process (
COMMAND bash -c "awk -F= '/^ID=/{print $2}' /etc/os-release |tr -d '\n' | tr -d '\"'"
OUTPUT_VARIABLE outOS
RESULT_VARIABLE outOS
)
if ( ${outOS} MATCHES "ubuntu" OR ${outOS} MATCHES "debian" OR ${outOS} MATCHES "FREEBSD" )
install(
FILES
${CMAKE_CURRENT_LIST_DIR}/rsc/rublon.config.defaults
${CMAKE_CURRENT_LIST_DIR}/rsc/rublon.config.defaults
${CMAKE_CURRENT_LIST_DIR}/service/01-rublon-ssh_pubkey.conf.default
${CMAKE_CURRENT_LIST_DIR}/service/01-rublon-ssh.conf.default
${CMAKE_CURRENT_LIST_DIR}/service/inst_pubkey.sh
DESTINATION
share/rublon
COMPONENT
@ -41,15 +47,20 @@ install(
OWNER_WRITE
GROUP_READ
)
if (NOT ${outOS} MATCHES "ubuntu" OR NOT ${outOS} MATCHES "debian" OR NOT ${outOS} MATCHES "FREEBSD")
else ()
install(
FILES
${CMAKE_CURRENT_LIST_DIR}/service/login_rublon.mod
${CMAKE_CURRENT_LIST_DIR}/service/login_rublon.pp
${CMAKE_CURRENT_LIST_DIR}/service/login_rublon.te
${CMAKE_CURRENT_LIST_DIR}/service/pam_service.txt
${CMAKE_CURRENT_LIST_DIR}/service/rublon_veritas
${CMAKE_CURRENT_LIST_DIR}/rsc/rublon.config.defaults
${CMAKE_CURRENT_LIST_DIR}/service/01-rublon-ssh_pubkey.conf.default
${CMAKE_CURRENT_LIST_DIR}/service/01-rublon-ssh.conf.default
${CMAKE_CURRENT_LIST_DIR}/service/login_rublon.mod
${CMAKE_CURRENT_LIST_DIR}/service/login_rublon.pp
${CMAKE_CURRENT_LIST_DIR}/service/login_rublon.te
${CMAKE_CURRENT_LIST_DIR}/service/pam_service.txt
${CMAKE_CURRENT_LIST_DIR}/service/rublon_veritas
${CMAKE_CURRENT_LIST_DIR}/service/inst_pubkey_rhel_9.sh
${CMAKE_CURRENT_LIST_DIR}/service/inst_pubkey_rhel_8.sh
${CMAKE_CURRENT_LIST_DIR}/service/inst_pubkey.sh
DESTINATION
share/rublon
COMPONENT

View File

@ -79,6 +79,7 @@ set(LWS_UNIX_SOCK OFF)
set(LWS_WITH_DIR OFF)
set(LWS_WITH_FILE_OPS OFF)
set(LWS_FOR_GITOHASHI OFF)
set(LWS_WITH_HTTP2 OFF)
set(LWS_WITH_HTTP_BASIC_AUTH OFF)
set(LWS_WITH_JPEG OFF)
@ -94,6 +95,9 @@ set(LWS_WITH_SECURE_STREAMS OFF)
set(LWS_WITH_WOL OFF)
set(LWS_WITH_UPNG OFF)
set(LWS_WITH_UDP OFF)
set(LWS_WITH_HTTP_STREAM_COMPRESSION OFF)
set(LWS_WITH_HTTP_BROTLI OFF)
set(LWS_WITH_ZLIB OFF)
set(RAPIDJSON_BUILD_DOC OFF CACHE BOOL "" FORCE)
set(RAPIDJSON_BUILD_EXAMPLES OFF CACHE BOOL "" FORCE)
@ -114,10 +118,17 @@ FetchContent_Declare(
FetchContent_MakeAvailable(libwebsockets)
set(RAPIDJSON_BUILD_DOC OFF)
set(RAPIDJSON_BUILD_EXAMPLES OFF)
set(RAPIDJSON_BUILD_TESTS OFF)
set(RAPIDJSON_HAS_STDSTRING OFF)
FetchContent_Declare(
RapidJSON
URL https://github.com/Tencent/rapidjson/archive/refs/tags/v1.1.0.zip
URL_HASH MD5=ceb1cf16e693a3170c173dc040a9d2bd
URL https://github.com/Tencent/rapidjson/archive/refs/tags/v1.1.0.zip
URL_HASH MD5=ceb1cf16e693a3170c173dc040a9d2bd
PATCH_COMMAND patch -p1 < ${CMAKE_CURRENT_LIST_DIR}/patches/rapidjson.patch
)
if(NOT RapidJSON_POPULATED)

View File

@ -29,6 +29,17 @@ class AuthenticationStep {
auto & alloc = body.GetAllocator();
body.AddMember("accessToken", Value{token.data(), static_cast< unsigned >(token.length()), alloc}, alloc);
}
template < typename Hander_t >
tl::expected< AuthenticationStatus, Error > waitForCoreConfirmation(const CoreHandlerInterface< Hander_t > & eventListener) const {
auto event = eventListener.listen();
if(event.status == transactionConfirmed ){
log(LogLevel::Debug, " Transaction confirmed");
return AuthenticationStatus{AuthenticationStatus::Action::Confirmed, std::string{event.accessToken.value().c_str()}};
}
log(LogLevel::Debug, " Transaction denied");
return AuthenticationStatus{AuthenticationStatus::Action::Denied};
}
};
} // namespace rublon

View File

@ -59,7 +59,7 @@ class Status {
std::ifstream ifs{_statusFilePath.data()};
if(!ifs.is_open()) {
/// TODO handle no file error
return;
}
rapidjson::IStreamWrapper isw{ifs};
@ -67,7 +67,7 @@ class Status {
}
void updateAppVersion(std::string_view newVersion) {
RapidJSONPMRStackAlloc< 128 > stackAlloc;
RapidJSONPMRStackAlloc< 512 > stackAlloc;
auto jsonPointer = JSONPointer{_appVersionKey.data(), &stackAlloc};
auto version = jsonPointer.Get(_data);
if(not version || version->GetString() != newVersion) {
@ -77,7 +77,7 @@ class Status {
}
void updateSystemVersion(std::string_view system) {
RapidJSONPMRStackAlloc< 128 > stackAlloc;
RapidJSONPMRStackAlloc< 512 > stackAlloc;
auto jsonPointer = JSONPointer{_paramSystemName.data(), &stackAlloc};
auto version = jsonPointer.Get(_data);
if(not version || version->GetString() != system) {
@ -88,7 +88,7 @@ class Status {
void updateSSHDConfig() {
using namespace std::string_view_literals;
constexpr auto keys = make_array("authenticationmethods"sv,
constexpr auto keys = make_array<std::string_view>("authenticationmethods"sv,
"challengeresponseauthentication"sv,
"kbdinteractiveauthentication"sv,
"logingracetime"sv,

View File

@ -27,6 +27,7 @@ class Configuration {
bool logging{};
bool autopushPrompt{};
FailMode failMode{};
bool nonInteractiveMode{};
};
namespace {
@ -138,7 +139,7 @@ constexpr auto make_entry(const char * name, const char * defaultValue) {
return Entry{name, defaultValue, Entry::make_read_function< member >()};
}
constexpr static inline std::array< Entry, 8 > configurationVariables = { //
constexpr static inline std::array< Entry, 9 > configurationVariables = { //
make_entry< &Configuration::logging >("logging", "true"),
make_entry< &Configuration::systemToken >("systemToken", nullptr),
make_entry< &Configuration::secretKey >("secretKey", nullptr),
@ -146,7 +147,9 @@ constexpr static inline std::array< Entry, 8 > configurationVariables = { //
make_entry< &Configuration::prompt >("prompt", "1"),
make_entry< &Configuration::enablePasswdEmail >("enablePasswdEmail", "true"),
make_entry< &Configuration::autopushPrompt >("autopushPrompt", "false"),
make_entry< &Configuration::failMode >("failMode", "deny")};
make_entry< &Configuration::failMode >("failMode", "deny"),
make_entry< &Configuration::nonInteractiveMode >("nonInteractiveMode", "false")
};
class ConfigurationFactory {
public:

View File

@ -1,5 +1,6 @@
#pragma once
#include "rublon/error.hpp"
#include "rublon/static_string.hpp"
#include <memory>
#include <optional>
@ -57,11 +58,13 @@ class CoreHandler : public CoreHandlerInterface< CoreHandler< HttpHandler > > {
}
bool hasException(const Document & coreResponse) const {
log(LogLevel::Trace, "Checking error status in core response");
using namespace std::string_view_literals;
return coreResponse.HasMember("status") and coreResponse["status"].GetString() == "ERROR"sv;
}
bool isUnHealthy(const Document & coreResponse) const {
log(LogLevel::Trace, "Checking errors in core response");
return coreResponse.HasParseError();
}
@ -102,7 +105,7 @@ class CoreHandler : public CoreHandlerInterface< CoreHandler< HttpHandler > > {
tl::expected< Document, Error > resp{&alloc};
resp->Parse(response.body.c_str());
log(LogLevel::Debug, "Begin, Core Response validation");
log(LogLevel::Debug, "Starting Core Response validation");
if(isUnHealthy(*resp)) {
log(LogLevel::Error, "Rublon Core responded with broken data");
@ -122,11 +125,13 @@ class CoreHandler : public CoreHandlerInterface< CoreHandler< HttpHandler > > {
// additional check for mallformed responses (A invalid response, without any x-rublon-signature will stop at this check)
return tl::unexpected{CoreHandlerError{CoreHandlerError::BadSigature}};
}
log(LogLevel::Debug, "Core Response validated OK");
return resp;
}
tl::unexpected< Error > handleCoreException(std::string_view exceptionString) const {
log(LogLevel::Debug, "TMP got core exception: %s", exceptionString.data() );
// can happen only dyring check application step
if(auto error = RublonCheckApplicationException::fromString(exceptionString); error.has_value())
return tl::unexpected{Error{error.value()}};
@ -138,9 +143,10 @@ class CoreHandler : public CoreHandlerInterface< CoreHandler< HttpHandler > > {
// verification error wrong passcode etc.
if(auto error = WerificationError::fromString(exceptionString); error.has_value())
return tl::unexpected{Error{error.value()}};
// CoreHandlerError::TransactionAccessTokenExpiredException
// other exceptions, just "throw"
// TODO Handle
return tl::unexpected{Error{CoreHandlerError{CoreHandlerError::RublonCoreException}}};
}

View File

@ -16,7 +16,7 @@ class CoreHandlerInterface {
}
bool createWSConnection(std::string_view tid) const {
rublon::log(LogLevel::Debug, "%s", "CoreHandlerInterface::listen");
rublon::log(LogLevel::Debug, "%s", "CoreHandlerInterface::createWSConnection");
return static_cast< const Impl * >(this)->createWSConnection(tid);
}

View File

@ -62,7 +62,6 @@ class CURL {
std::pmr::string response_data{&stackResource};
response_data.reserve(3000);
/// 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) {
log(LogLevel::Debug, "%s header: %s: %s", "CURL", header.first.c_str(), header.second.c_str());

View File

@ -1,17 +1,14 @@
#pragma once
#include <string_view>
#include <tl/expected.hpp>
#include <rublon/non_owning_ptr.hpp>
#include <rublon/stdlib.hpp>
#include <rublon/utils.hpp>
namespace rublon {
template < typename... Types >
constexpr std::array< std::string_view, sizeof...(Types) > make_array(Types... names) {
return {std::forward< Types >(names)...};
}
class ConfigurationError {
public:
enum class ErrorClass { //
@ -20,7 +17,7 @@ class ConfigurationError {
BadInput,
Empty
};
constexpr static auto errorClassPrettyName = make_array( //
constexpr static auto errorClassPrettyName = make_array< std::string_view >( //
"RequiredValueNotFound",
"BadFailMode",
"BadInput",
@ -43,7 +40,7 @@ class ConnectionError {
HttpError,
ClientError
};
constexpr static auto errorClassPrettyName = make_array( //
constexpr static auto errorClassPrettyName = make_array< std::string_view >( //
"Timeout",
"Error",
"Client Error");
@ -72,7 +69,7 @@ class CoreHandlerError {
TransactionAccessTokenExpiredException, // code: 11
TooManyRequestsException
};
constexpr static auto errorClassPrettyName = make_array( //
constexpr static auto errorClassPrettyName = make_array< std::string_view >( //
"BadSigature",
"RublonCoreException",
"BrokenData",
@ -107,7 +104,7 @@ class CoreHandlerError {
class MethodError {
public:
enum ErrorClass { BadMethod, BadUserInput, NoMethodAvailable };
constexpr static auto errorClassPrettyName = make_array("BadMethod", "BadUserInput", "NoMethodAvailable");
constexpr static auto errorClassPrettyName = make_array< std::string_view >("BadMethod", "BadUserInput", "NoMethodAvailable");
constexpr static auto prettyName = "Method Error";
constexpr MethodError(ErrorClass e = BadMethod) : errorClass{e} {}
@ -127,7 +124,7 @@ class WerificationError {
PasscodeException, // code: 18
TooManyRequestsException // code: 101
};
constexpr static auto errorClassPrettyName = make_array( //
constexpr static auto errorClassPrettyName = make_array< std::string_view >( //
"BadInput",
"SecurityKeyException",
"PasscodeException",
@ -162,7 +159,7 @@ class RublonAuthenticationInterrupt {
UserWaiting,
UserNotFound
};
constexpr static auto errorClassPrettyName = make_array( //
constexpr static auto errorClassPrettyName = make_array< std::string_view >( //
"UserBypassedException",
"UserDenied",
"UserPending",
@ -197,7 +194,7 @@ class RublonCheckApplicationException {
UnsupportedVersionException
};
constexpr static auto errorClassPrettyName = make_array( //
constexpr static auto errorClassPrettyName = make_array< std::string_view >( //
"MissingFieldException",
"ApplicationNotFoundException",
"InvalidSignatureException",

View File

@ -1,6 +1,7 @@
#pragma once
#include "rublon/memory.hpp"
#include "rublon/utils.hpp"
#include <rublon/bits.hpp>
#include <rublon/authentication_step_interface.hpp>
@ -23,16 +24,19 @@ class Init : public AuthenticationStep {
const char * apiPath = "/api/transaction/init";
tl::expected< MethodSelect_t, Error > createMethod(const Document & coreResponse) const {
memory::MonotonicStackResource< 256 > stackResource;
memory::MonotonicStackResource< 512 > stackResource;
RapidJSONPMRAlloc alloc{&stackResource};
const auto & rublonResponse = coreResponse["result"];
// const auto * rublonMethods = JSONPointer{"/result/methods", &alloc}.Get(coreResponse);
const auto * rublonMethods = JSONPointer{"/result/methods", &alloc}.Get(coreResponse);
const auto * rublonTid = JSONPointer{"/result/tid", &alloc}.Get(coreResponse);
_session.updateTransactionId(rublonTid);
return MethodSelect_t{_session, rublonResponse["methods"], _session.config().prompt, _session.config().autopushPrompt};
if(not rublonMethods)
log(LogLevel::Error, "core response has no methods");
if(not rublonTid)
log(LogLevel::Error, "core response has no transaction ID");
_session.updateTransactionId(rublonTid);
return MethodSelect_t{_session, *rublonMethods, _session.config().prompt, _session.config().autopushPrompt};
}
void addPamInfo(Document & coreRequest, const Pam_t & pam) const {
@ -41,39 +45,45 @@ class Init : public AuthenticationStep {
}
void addParams(Document & coreRequest, const Pam_t & pam) const {
memory::MonotonicStackResource< 512 > stackResource;
memory::MonotonicStackResource< 1024 > stackResource;
std::pmr::string releaseInfo{&stackResource};
auto & alloc = coreRequest.GetAllocator();
const auto os = details::osName(&stackResource);
const auto host = details::hostname(&stackResource);
if(os == "unknown") {
log(LogLevel::Warning, "No OS information available");
}
Value osNamePretty{os.data(), static_cast< unsigned >(os.size()), alloc};
Value ip{pam.ip().get(), alloc};
Value params{rapidjson::kObjectType};
params.AddMember("userIP", ip, alloc);
params.AddMember("appVer", RUBLON_VERSION_STRING, alloc);
params.AddMember("os", osNamePretty, alloc);
if(not host.empty())
params.AddMember("hostName", Value{os.c_str(), static_cast< unsigned >(host.size()), alloc}, alloc);
if(not _session.inInteractiveMode())
params.AddMember("mode", "noninteractive", alloc);
params.AddMember("os", Value{os.c_str(), static_cast< unsigned >(os.size()), alloc}, alloc);
params.AddMember("userIP", Value{pam.ip().get(), alloc}, alloc);
coreRequest.AddMember("params", std::move(params), alloc);
}
tl::expected< std::reference_wrapper< const Document >, Error > checkEnrolement(const Document & coreResponse, const Pam_t pam) const {
using namespace std::string_view_literals;
const auto & resp = coreResponse;
memory::MonotonicStackResource< 256 > stackResource;
RapidJSONPMRAlloc alloc{&stackResource};
/// TODO refactor this
if(resp.HasMember("result") and resp["result"].IsObject() and resp["result"].HasMember("status")) {
const auto & status = resp["result"]["status"].GetString();
const auto * rublonStatus = JSONPointer{"/result/status", &alloc}.Get(coreResponse);
const auto * rublonWebURI = JSONPointer{"/result/webURI", &alloc}.Get(coreResponse);
if(rublonStatus) {
const auto & status = rublonStatus->GetString();
log(LogLevel::Warning, "Got enrolement message with stats %s", status);
if(status == "pending"sv) {
if(resp["result"].HasMember("webURI")) {
const auto & weburi = resp["result"]["webURI"].GetString();
pam.print("Visit %s", weburi);
if(rublonWebURI) {
pam.print("Visit %s", rublonWebURI->GetString());
}
} else if(status == "waiting"sv) {
return tl::unexpected{Error{RublonAuthenticationInterrupt{RublonAuthenticationInterrupt::UserWaiting}}};

View File

@ -1,5 +1,6 @@
#pragma once
#include "rapidjson/encodings.h"
#include <rapidjson/document.h>
#include <rapidjson/istreamwrapper.h>
#include <rapidjson/pointer.h>
@ -137,7 +138,6 @@ inline auto begin(const rublon::Value & __ils) noexcept {
inline ::rublon::Value::ConstValueIterator end(const rublon::Value & __ils) noexcept {
return __ils.End();
}
[[nodiscard]] inline std::size_t size(const rublon::Value & __cont) {
return __cont.Size();
}

View File

@ -13,7 +13,6 @@ class OTP : public PasscodeBasedAuth {
public:
OTP(Session & session, int prompts)
: PasscodeBasedAuth(session,
"",
"Mobile Passcode",
"Enter the passcode from the Authenticator app: ",
6,

View File

@ -1,6 +1,5 @@
#pragma once
#include "rublon/session.hpp"
#include <tl/expected.hpp>
#include <rublon/authentication_step_interface.hpp>

View File

@ -12,7 +12,7 @@ namespace rublon::method {
class SMS : public PasscodeBasedAuth {
public:
SMS(Session & session, int prompts)
: PasscodeBasedAuth(session, "", "SMS", "Enter SMS passcode: ", 6, true, PasscodeBasedAuth::Endpoint::ConfirmCode, prompts) {}
: PasscodeBasedAuth(session, "SMS", "Enter SMS passcode: ", 6, true, PasscodeBasedAuth::Endpoint::ConfirmCode, prompts) {}
};
} // namespace rublon::method

View File

@ -11,9 +11,8 @@ namespace rublon::method {
class YOTP : public PasscodeBasedAuth {
public:
YOTP(Session & session, std::string accessToken, int prompts)
YOTP(Session & session, int prompts)
: PasscodeBasedAuth(session,
std::move(accessToken),
"YubiKey OTP Security Key",
"Insert and tap your YubiKey: ",
44,

View File

@ -1,11 +1,16 @@
#pragma once
#include "rublon/session.hpp"
#include <algorithm>
#include <set>
#include <string_view>
#include <tl/expected.hpp>
#include <rublon/bits.hpp>
#include <rublon/error.hpp>
#include <rublon/json.hpp>
#include <rublon/memory.hpp>
#include <rublon/pam_action.hpp>
#include <rublon/session.hpp>
#include <rublon/utils.hpp>
#include <rublon/method/EMAIL.hpp>
#include <rublon/method/PUSH.hpp>
@ -18,6 +23,9 @@
namespace rublon {
enum class MethodIds { OTP, SMS, PUSH, EMAIL, SmsLink, YOTP, PhoneCall };
constexpr auto MethodNames = make_array< std::string_view >("totp", "sms", "push", "email", "smsLink", "yotp", "phoneCall");
class MethodProxy {
public:
template < typename Method_t >
@ -43,49 +51,63 @@ class PostMethod : public AuthenticationStep {
using base_t = AuthenticationStep;
const char * uri = "/api/transaction/methodSSH";
std::string _method;
MethodIds _method;
int _prompts;
bool _autopushPrompt;
tl::expected< MethodProxy, Error > createMethod(const Document & coreResponse) const {
/// TODO vericodeLength
const auto & rublonResponse = coreResponse["result"];
// [[deprecated]] std::string tid = rublonResponse["tid"].GetString();
tl::expected< void, Error > readAccessToken(const Document & coreResponse) const {
log(LogLevel::Debug, "Readding access token");
auto alloc = RapidJSONPMRStackAlloc< 256 >{};
const auto * rublonAccessToken = JSONPointer{"/result/token", &alloc}.Get(coreResponse);
if(rublonAccessToken)
_session.updateAccessToken(rublonAccessToken);
return {};
}
if(_method == "totp") {
return MethodProxy{method::OTP{_session, _prompts}};
} else if(_method == "sms") {
return MethodProxy{method::SMS{_session, _prompts}};
} else if(_method == "push") {
return MethodProxy{method::PUSH{_session, _autopushPrompt}};
} else if(_method == "email") {
return MethodProxy{method::EMAIL{_session}};
} else if(_method == "smsLink") {
return MethodProxy{method::SmsLink{_session}};
} else if(_method == "yotp") {
/// TODO assert has token
std::string token = rublonResponse.HasMember("token") ? rublonResponse["token"].GetString() : "";
return MethodProxy{method::YOTP{_session, std::move(token), _prompts}};
} else if(_method == "phoneCall") {
return MethodProxy{method::PhoneCall{_session}};
} else
return tl::unexpected{MethodError{MethodError::BadMethod}};
tl::expected< MethodProxy, Error > createMethod() const {
log(LogLevel::Debug, "Creating method");
switch(_method) {
case rublon::MethodIds::OTP:
return MethodProxy{method::OTP{_session, _prompts}};
case rublon::MethodIds::SMS:
return MethodProxy{method::SMS{_session, _prompts}};
case rublon::MethodIds::PUSH:
return MethodProxy{method::PUSH{_session, _autopushPrompt}};
case rublon::MethodIds::EMAIL:
return MethodProxy{method::EMAIL{_session}};
case rublon::MethodIds::SmsLink:
return MethodProxy{method::SmsLink{_session}};
case rublon::MethodIds::YOTP:
return MethodProxy{method::YOTP{_session, _prompts}};
case rublon::MethodIds::PhoneCall:
return MethodProxy{method::PhoneCall{_session}};
default:
return tl::unexpected{MethodError{MethodError::BadMethod}};
}
}
void addParams(Document & body) const {
auto & alloc = body.GetAllocator();
body.AddMember("method", Value{_method.c_str(), alloc}, alloc);
body.AddMember("method", Value{MethodNames[static_cast< int >(_method)].data(), alloc}, alloc);
}
public:
const char * _name = "Confirm Method";
PostMethod(Session & session, std::string method, int prompts, bool autopushPrompt)
PostMethod(Session & session, MethodIds method, int prompts, bool autopushPrompt)
: base_t(session), _method{method}, _prompts{prompts}, _autopushPrompt{autopushPrompt} {}
template < typename Hander_t >
tl::expected< MethodProxy, Error > handle(const CoreHandlerInterface< Hander_t > & coreHandler) const {
auto createMethod = [&](const auto & coreResponse) { return this->createMethod(coreResponse); };
auto readAccessToken = [&](const auto & coreResponse) { return this->readAccessToken(coreResponse); };
auto createMethod = [&]() { return this->createMethod(); };
RapidJSONPMRStackAlloc< 2 * 1024 > alloc{};
Document body{rapidjson::kObjectType, &alloc};
@ -96,6 +118,7 @@ class PostMethod : public AuthenticationStep {
return coreHandler
.request(alloc, uri, body) //
.and_then(readAccessToken)
.and_then(createMethod);
}
};
@ -110,31 +133,29 @@ class MethodSelect {
public:
template < typename Array_t >
MethodSelect(Session & session, const Array_t & methodsAvailableForUser, int prompts, bool autopushPrompt)
MethodSelect(Session & session, const Array_t & methodsEnabledInCore, int prompts, bool autopushPrompt)
: _session{session}, _prompts{prompts}, _autopushPrompt{autopushPrompt} {
rublon::log(LogLevel::Debug, "Checking what methods from core are supported");
using namespace std::string_view_literals;
memory::MonotonicStackResource< 2024 > stackResource;
std::pmr::vector< std::string_view > _methods;
_methodsAvailable.reserve(std::size(methodsAvailableForUser));
std::pmr::set< std::string_view > methodsSupported{
{"totp"sv, "email"sv, "yotp"sv, "sms"sv, "push"sv, "smsLink"sv, "phoneCall"sv}, &stackResource};
_methodsAvailable.reserve(std::size(methodsEnabledInCore));
transform_if(
std::begin(methodsAvailableForUser),
std::end(methodsAvailableForUser),
std::begin(methodsEnabledInCore),
std::end(methodsEnabledInCore),
std::back_inserter(_methodsAvailable),
[&](const auto & method) { return method.GetString(); },
[&](const auto & method) { return methodsSupported.find(method.GetString()) != methodsSupported.end(); });
[&](const auto & method) { return std::find(MethodNames.begin(), MethodNames.end(), method.GetString()) != MethodNames.end(); });
rublon::log(LogLevel::Debug, "User has %d methods available", _methodsAvailable.size());
}
tl::expected< PostMethod, Error > create(Pam_t & pam) const {
rublon::log(LogLevel::Debug, "prompting user to select method");
memory::StrictMonotonic_4k_HeapResource memoryResource;
std::pmr::map< int, std::string > methods_id{&memoryResource}; /// TODO pmr
memory::StrictMonotonic_2k_HeapResource memoryResource;
std::pmr::map< int, MethodIds > methods_id{&memoryResource};
std::pmr::map< int, std::pmr::string > methods_names{&memoryResource};
int prompts = _prompts;
if(_methodsAvailable.size() == 0) {
@ -147,65 +168,95 @@ class MethodSelect {
auto logMethodAvailable = [](auto & method) { //
rublon::log(LogLevel::Debug, "Method %s found", method.c_str());
};
auto logMethodSkippedInteractive = [](auto & method) {
rublon::log(LogLevel::Debug, "Method %s found, but skipped due non interactive mode", method.c_str());
};
auto logMethodNotAvailable = [](auto & method) {
rublon::log(LogLevel::Debug, "Method %s found, but has no handler", method.c_str());
};
auto printAvailableMethods = [&]() -> tl::expected< int, MethodError > {
rublon::log(LogLevel::Trace, "Printing available methods");
int i{};
for(const auto & method : _methodsAvailable) {
if(method == "totp") {
// skipped in non interactive
if(not _session.inInteractiveMode()) {
logMethodSkippedInteractive(method);
continue;
}
logMethodAvailable(method);
pam.print("%d: Passcode", i + 1);
methods_id[++i] = method;
if(_session.inInteractiveMode())
pam.print("%d: Passcode", i + 1);
methods_id[++i] = MethodIds::OTP;
methods_names[i] = "Passcode";
continue;
}
if(method == "email") {
// available in non interactive
logMethodAvailable(method);
pam.print("%d: Email Link", i + 1);
methods_id[++i] = method;
if(_session.inInteractiveMode())
pam.print("%d: Email Link", i + 1);
methods_id[++i] = MethodIds::EMAIL;
methods_names[i] = "Email Link";
continue;
}
if(method == "yotp") {
// skipped in non interactive
if(not _session.inInteractiveMode()) {
logMethodSkippedInteractive(method);
continue;
}
logMethodAvailable(method);
pam.print("%d: YubiKey OTP Security Key", i + 1);
methods_id[++i] = method;
if(_session.inInteractiveMode())
pam.print("%d: YubiKey OTP Security Key", i + 1);
methods_id[++i] = MethodIds::YOTP;
methods_names[i] = "YubiKey OTP Security Key";
continue;
}
if(method == "sms") {
// skipped in non interactive
if(not _session.inInteractiveMode()) {
logMethodSkippedInteractive(method);
continue;
}
logMethodAvailable(method);
pam.print("%d: SMS Passcode", i + 1);
methods_id[++i] = method;
if(_session.inInteractiveMode())
pam.print("%d: SMS Passcode", i + 1);
methods_id[++i] = MethodIds::SMS;
methods_names[i] = "SMS Passcode";
continue;
}
if(method == "push") {
// available in non interactive
logMethodAvailable(method);
pam.print("%d: Mobile Push", i + 1);
methods_id[++i] = method;
if(_session.inInteractiveMode())
pam.print("%d: Mobile Push", i + 1);
methods_id[++i] = MethodIds::PUSH;
methods_names[i] = "Mobile Push";
continue;
}
if(method == "smsLink") {
// available in non interactive
logMethodAvailable(method);
pam.print("%d: SMS Link", i + 1);
methods_id[++i] = method;
if(_session.inInteractiveMode())
pam.print("%d: SMS Link", i + 1);
methods_id[++i] = MethodIds::SmsLink;
methods_names[i] = "SMS Link";
continue;
}
if(method == "phoneCall") {
// available in non interactive
logMethodAvailable(method);
pam.print("%d: Phone Call", i + 1);
methods_id[++i] = method;
if(_session.inInteractiveMode())
pam.print("%d: Phone Call", i + 1);
methods_id[++i] = MethodIds::PhoneCall;
methods_names[i] = "Phone Call";
continue;
}
@ -225,8 +276,8 @@ class MethodSelect {
};
const auto createMethod = [&](std::uint32_t methodid) -> tl::expected< PostMethod, MethodError > {
rublon::log(LogLevel::Trace, "Create method %d", methods_id);
auto hasMethod = methods_id.find(methodid) != methods_id.end();
// pam.print("\t selected: %s", hasMethod ? methods_id.at(methodid).c_str() : "unknown option");
if(!hasMethod) {
log(LogLevel::Error, "User selected option %d, which is not correct", methodid);
return tl::unexpected{MethodError(MethodError::BadMethod)};
@ -237,14 +288,36 @@ class MethodSelect {
};
const auto askForMethod = [&](int methods_number) -> tl::expected< uint32_t, MethodError > {
if(methods_number == 1) {
pam.print("Automatically selected the only available authentication method: %s", methods_id.at(1).c_str());
return 1;
if(not _session.inInteractiveMode()) {
log(LogLevel::Debug, "Non interactive method selection");
/// TODO refactor, this is ugly
auto nonInteractiveMethodsPriority =
make_array< MethodIds >(MethodIds::PUSH, MethodIds::EMAIL, MethodIds::SmsLink, MethodIds::PhoneCall);
for(const auto methodid : nonInteractiveMethodsPriority) {
for(auto [key, id] : methods_id) {
if(id == methodid) {
log(LogLevel::Debug,
"Automatically selected authentication method: %s due to working in noninteractive mode",
methods_names.at(key).c_str());
pam.print("Non-interctive mode enabled, choose method: %s", methods_names.at(key).c_str());
return key;
}
}
}
return tl::unexpected{MethodError(MethodError::BadMethod)};
} else {
if(methods_number == 1) {
pam.print("Automatically selected the only available authentication method: %s", methods_names.at(1).c_str());
return 1;
}
return pam.scan(conv::to_uint32, "\nSelect method [1-%d]: ", methods_number).transform_error(toMethodError);
}
return pam.scan(conv::to_uint32, "\nSelect method [1-%d]: ", methods_number).transform_error(toMethodError);
};
auto reducePromptCount = [&](int selected_method) -> tl::expected< uint32_t, MethodError > {
rublon::log(LogLevel::Trace, "User has %d prompts available", prompts);
prompts--;
return selected_method;
};

View File

@ -58,6 +58,7 @@ class PasscodeBasedAuth : public AuthenticationStep {
}
tl::expected< std::reference_wrapper< Document >, Error > readPasscode(Document & body, const Pam_t & pam) const {
///TODO assert in interactive mode
auto & alloc = body.GetAllocator();
auto vericode = pam.scan([](const char * userInput) { return std::string{userInput}; }, userMessage);
@ -65,8 +66,8 @@ class PasscodeBasedAuth : public AuthenticationStep {
Value confirmFieldValue(confirmField, alloc);
body.AddMember(confirmFieldValue, Value{vericode.c_str(), alloc}, alloc);
if(token.size()) {
this->addAccessToken(body, token);
if(_session.hasAccessToken()) {
this->addAccessToken(body, _session.accessToken());
}
return body;
}
@ -79,18 +80,6 @@ class PasscodeBasedAuth : public AuthenticationStep {
return AuthenticationStatus{AuthenticationStatus::Action::Confirmed};
}
template < typename Hander_t >
tl::expected< AuthenticationStatus, Error > waitForCoreConfirmation(const CoreHandlerInterface< Hander_t > & eventListener) const {
log(LogLevel::Info, "Listening to confirmation event in PasscodeBasedAuth");
auto event = eventListener.listen();
if(event.status == transactionConfirmed ){
log(LogLevel::Debug, " transaction confirmed jupi");
return AuthenticationStatus{AuthenticationStatus::Action::Confirmed, std::string{event.accessToken.value().c_str()}};
}
log(LogLevel::Debug, " transaction denied");
return AuthenticationStatus{AuthenticationStatus::Action::Denied};
}
tl::expected< AuthenticationStatus, Error > errorHandler(Error error, const Pam_t & pam, int promptLeft) const {
if(promptLeft && error.is< WerificationError >()) {
@ -114,13 +103,11 @@ class PasscodeBasedAuth : public AuthenticationStep {
public:
const char * _name;
std::string token; // TODO StaticString
enum class Endpoint { ConfirmCode, SecurityKeySSH };
PasscodeBasedAuth( //
Session & session,
std::string token,
const char * _name,
const char * userMessage,
@ -135,8 +122,7 @@ class PasscodeBasedAuth : public AuthenticationStep {
vericodeLength{length},
onlyDigits{numbersOnly},
_prompts{prompts},
_name{_name},
token{std::move(token)} {}
_name{_name} {}
template < typename Hander_t >
tl::expected< AuthenticationStatus, Error > verify(const CoreHandlerInterface< Hander_t > & coreHandler, const Pam_t & pam) const {

View File

@ -6,37 +6,39 @@
#include <rublon/bits.hpp>
#include <rublon/configuration.hpp>
#include <rublon/pam_action.hpp>
#include <rublon/websockets.hpp>
namespace rublon::method {
class WebsocketBasedAuth : public AuthenticationStep {
tl::expected< void, Error > prompt(const Pam_t & pam) const {
if(not _session.inInteractiveMode()) {
return {};
}
if(not _autopushPrompt)
pam.print("Autopush");
else
pam.scan([](const auto /*ignored userinput*/) { return ""; },
"Rublon authentication initiated. Complete the authentication and press Enter to proceed");
return {};
}
public:
const char * _name = "";
const bool _autopushPrompt = true;
WebsocketBasedAuth(Session & session, const char * name, bool autopushPrompt = true)
: AuthenticationStep(session), _name{name}, _autopushPrompt{autopushPrompt} {}
/// TODO refactor this code
template < typename Hander_t >
tl::expected< AuthenticationStatus, Error > verify(const CoreHandlerInterface< Hander_t > & coreHandler, const Pam_t & pam) const {
log(LogLevel::Info, "starting WS");
if(not _autopushPrompt)
pam.print("Autopush");
else
pam.scan([](const auto /*ignored userinput*/) { return ""; },
"Rublon authentication initiated. Complete the authentication and press Enter to proceed");
RublonEventData event = coreHandler.listen();
if(event.status == transactionConfirmed ){
log(LogLevel::Debug, " transaction confirmed jupi");
return AuthenticationStatus{AuthenticationStatus::Action::Confirmed, std::string{event.accessToken.value().c_str()}};
}
log(LogLevel::Debug, " transaction denied");
return AuthenticationStatus{AuthenticationStatus::Action::Denied};
const auto promprUser = [&]() { return prompt(pam); };
const auto waitForCoreToConfirm = [&]() { return waitForCoreConfirmation(coreHandler); };
return promprUser() //
.and_then(waitForCoreToConfirm);
}
};

View File

@ -1,5 +1,6 @@
#pragma once
#include <security/_pam_types.h>
#include <security/pam_appl.h>
#include <security/pam_client.h>
#include <security/pam_ext.h>
@ -20,7 +21,7 @@ class LinuxPam {
const void * ip = NULL;
pam_get_item(pamh, PAM_RHOST, &ip);
if(ip == NULL) {
rublon::log(rublon::LogLevel::Warning, "Cant read user from linux PAM");
rublon::log(rublon::LogLevel::Warning, "Cant read ip from linux PAM");
ip = "";
}
return ( const char * ) ip;
@ -40,8 +41,6 @@ class LinuxPam {
void print(const char * fmt, Ti... ti) const noexcept {
char buf[256] = {};
sprintf(buf, fmt, std::forward< Ti >(ti)...);
log(LogLevel::Debug, "pam_print: '%s'", buf);
if(auto r = pam_prompt(pamh, PAM_TEXT_INFO, nullptr, fmt, std::forward< Ti >(ti)...); r != PAM_SUCCESS) {
log(LogLevel::Error, "pam_print returned with error code %d", r);
}

View File

@ -5,6 +5,7 @@
#include <rublon/bits.hpp>
#include <rublon/configuration.hpp>
#include <rublon/json.hpp>
#include <string>
#include <string_view>
namespace rublon {
@ -14,20 +15,22 @@ class Session {
const Configuration _config;
std::pmr::string _tid;
std::pmr::string _accessToken;
CoreHandler_t _coreHandler;
/// TODO log
/// TODO momory resource
public:
Session(const Pam_t & pam, const Configuration & config) : _pam{pam}, _config{config}, _coreHandler{_config} {
Session(const Pam_t & pam, const Configuration & config)
: _pam{pam}, _config{config}, _coreHandler{_config} {
log(LogLevel::Debug, __PRETTY_FUNCTION__);
}
Session(Session &&) noexcept = default;
Session(const Session &) = delete;
Session& operator=(Session &&) noexcept = default;
Session& operator=(const Session &) = delete;
Session & operator=(Session &&) noexcept = delete;
Session & operator=(const Session &) = delete;
const auto & coreHandler() const {
return _coreHandler;
@ -46,13 +49,27 @@ class Session {
return systemToken().data();
}
/// TODO validate tid
bool inInteractiveMode() const {
return _config.nonInteractiveMode == false;
}
void updateTransactionId(const Value * tid) {
if(tid == nullptr) {
log(LogLevel::Warning, "Transaction ID is not defined");
} else {
_tid = tid->GetString();
}
log(LogLevel::Debug, "Set transaction ID %s", tid->GetString());
_tid = tid->GetString();
}
void updateAccessToken(const Value * accessToken) {
log(LogLevel::Debug, "AccessToken %s", accessToken->GetString());
_accessToken = accessToken->GetString();
}
bool hasAccessToken() const {
return not _accessToken.empty();
}
std::string_view accessToken() const {
return _accessToken;
}
const char * caccessToken() const {
return _accessToken.c_str();
}
std::string_view transactionID() const {

View File

@ -5,6 +5,7 @@
#include <rublon/stdlib.hpp>
#include <fcntl.h>
#include <string>
#include <sys/stat.h>
#include <syslog.h>
#include <unistd.h>
@ -33,7 +34,7 @@ inline bool readFile(const std::filesystem::path & path, T & destination) {
return true;
}
enum class LogLevel { Debug, Info, Warning, Error };
enum class LogLevel { Trace, Debug, Info, Warning, Error };
inline StaticString< 32 > dateStr() {
StaticString< 32 > date;
@ -43,45 +44,12 @@ inline StaticString< 32 > dateStr() {
return date;
}
constexpr const char * LogLevelNames[]{"Debug", "Info", "Warning", "Error"};
constexpr const char * LogLevelNames[]{"Trace", "Debug", "Info", "Warning", "Error"};
LogLevel g_level = LogLevel::Debug;
constexpr bool syncLogFile = true;
static const char * application = "";
namespace details {
std::pmr::string osName(std::pmr::memory_resource * mr) {
memory::MonotonicStackResource< 8 * 1024 > stackResource;
std::ifstream file(std::filesystem::path{"/etc/os-release"});
if(not file.good())
return {"unknown", mr};
std::pmr::string line{&stackResource};
line.reserve(100);
while(std::getline(file, line)) {
std::pmr::string _key{&stackResource};
std::pmr::string _value{&stackResource};
if(!line.length())
continue;
if(line[0] == '#' || line[0] == ';')
continue;
auto posEqual = line.find('=');
_key = line.substr(0, posEqual);
_value = line.substr(posEqual + 1);
if(_key == "PRETTY_NAME") {
_value.erase(std::remove_if(_value.begin(), _value.end(), [](auto ch) { return ch == '"'; }), _value.end());
return {_value, mr};
}
}
return {"unknown", mr};
}
constexpr const char * logPath() {
constexpr auto path = "/var/log/rublon-ssh.log";
return path;
@ -228,6 +196,49 @@ namespace details {
}
}
std::pmr::string hostname(std::pmr::memory_resource * mr) {
std::pmr::string hostname{512, '\0', mr};
if(gethostname(hostname.data(), hostname.size()) != 0) {
log(LogLevel::Warning, "Hostname is not available");
return "";
}
hostname.resize(hostname.find_first_of('\0'));
return hostname;
}
std::pmr::string osName(std::pmr::memory_resource * mr) {
memory::MonotonicStackResource< 8 * 1024 > stackResource;
std::ifstream file(std::filesystem::path{"/etc/os-release"});
if(not file.good())
return {"unknown", mr};
std::pmr::string line{&stackResource};
line.reserve(100);
while(std::getline(file, line)) {
std::pmr::string _key{&stackResource};
std::pmr::string _value{&stackResource};
if(!line.length())
continue;
if(line[0] == '#' || line[0] == ';')
continue;
auto posEqual = line.find('=');
_key = line.substr(0, posEqual);
_value = line.substr(posEqual + 1);
if(_key == "PRETTY_NAME") {
_value.erase(std::remove_if(_value.begin(), _value.end(), [](auto ch) { return ch == '"'; }), _value.end());
return {_value, mr};
}
}
return {"unknown", mr};
}
} // namespace details
template < class InputIterator, class OutputIterator, class UnaryOperator, class Pred >
@ -250,4 +261,9 @@ struct ci_less {
}
};
template < typename Out, typename... Types >
constexpr std::array< Out, sizeof...(Types) > make_array(Types... names) {
return {std::forward< Types >(names)...};
}
} // namespace rublon

View File

@ -201,8 +201,10 @@ class WebSocket {
if(input.substr(0, 2) == "42") {
/// TODO assert _this
/// TODO assert currentEvent
/// TODO refactor to separate class
if(_this->currentEvent == nullptr)
return -1;
log(LogLevel::Debug, "WS got %s", input.data());
size_t startPos = input.find("[\"") + 2;
size_t endPos = input.find("\",", startPos);
auto & event = *_this->currentEvent;
@ -222,7 +224,8 @@ class WebSocket {
Document dataJson{&alloc};
dataJson.Parse(jsonString.data(), jsonString.size());
const auto * data = JSONPointer{"/data", &alloc}.Get(dataJson);
const auto * data = JSONPointer{"/data", &alloc}.Get(dataJson);
const auto * redirectUrl = JSONPointer{"/redirectUrl", &alloc}.Get(dataJson);
if(data != nullptr) {
Document tokenJson{&alloc};
@ -232,10 +235,11 @@ class WebSocket {
if(token != nullptr) {
event.accessToken = token->GetString();
} else {
log(LogLevel::Debug, "got broken data");
log(LogLevel::Error, "Response does not contain token");
}
log(LogLevel::Debug, "mark event received");
_this->event_received = true;
} else if(redirectUrl != nullptr) {
log(LogLevel::Info, "Received deny message");
_this->event_received = true;
} else {
log(LogLevel::Error, "event data incorrect");

View File

@ -33,18 +33,23 @@ pam_sm_authenticate(pam_handle_t * pamh, [[maybe_unused]] int flags, [[maybe_unu
using namespace rublon;
details::initLog();
LinuxPam pam{pamh};
log(LogLevel::Info, "user '%s' authentication attempt", pam.username().get());
auto printAuthMessageAndExit = [&](const AuthenticationStatus status) {
switch(status.action()) {
case AuthenticationStatus::Action::Bypass:
log(LogLevel::Info, "user '%s' authentication BYPASSED", pam.username().get());
pam.print("RUBLON authentication BYPASSED");
return PAM_SUCCESS;
case AuthenticationStatus::Action::Denied:
log(LogLevel::Info, "user '%s' authentication FAILED", pam.username().get());
pam.print("RUBLON authentication FAILED");
return PAM_MAXTRIES;
case AuthenticationStatus::Action::Confirmed:
log(LogLevel::Info, "user '%s' authentication SUCCEEDED", pam.username().get());
pam.print("RUBLON authentication SUCCEEDED");
return PAM_SUCCESS;
}
@ -95,8 +100,8 @@ pam_sm_authenticate(pam_handle_t * pamh, [[maybe_unused]] int flags, [[maybe_unu
{
CheckApplication ca;
auto ret =
ca.call(CH, {session.value().config().systemToken.data(), session.value().config().systemToken.size()}).or_else(mapError);
const auto & config = session.value().config();
const auto ret = ca.call(CH, {config.systemToken.data(), config.systemToken.size()}).or_else(mapError);
if(not ret.has_value()) {
log(LogLevel::Error, "Check Application step failed, check configration");
return PAM_MAXTRIES;

View File

@ -0,0 +1,51 @@
diff --git a/include/rapidjson/document.h b/include/rapidjson/document.h
index e3e20dfb..592c5678 100644
--- a/include/rapidjson/document.h
+++ b/include/rapidjson/document.h
@@ -97,17 +97,20 @@ struct GenericMember {
\see GenericMember, GenericValue::MemberIterator, GenericValue::ConstMemberIterator
*/
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
template <bool Const, typename Encoding, typename Allocator>
class GenericMemberIterator
: public std::iterator<std::random_access_iterator_tag
, typename internal::MaybeAddConst<Const,GenericMember<Encoding,Allocator> >::Type> {
-
+
friend class GenericValue<Encoding,Allocator>;
template <bool, typename, typename> friend class GenericMemberIterator;
typedef GenericMember<Encoding,Allocator> PlainType;
typedef typename internal::MaybeAddConst<Const,PlainType>::Type ValueType;
typedef std::iterator<std::random_access_iterator_tag,ValueType> BaseType;
+#pragma GCC diagnostic pop
public:
//! Iterator type itself
@@ -1936,7 +1939,10 @@ private:
if (count) {
GenericValue* e = static_cast<GenericValue*>(allocator.Malloc(count * sizeof(GenericValue)));
SetElementsPointer(e);
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wclass-memaccess"
std::memcpy(e, values, count * sizeof(GenericValue));
+#pragma GCC diagnostic pop
}
else
SetElementsPointer(0);
@@ -1949,7 +1955,10 @@ private:
if (count) {
Member* m = static_cast<Member*>(allocator.Malloc(count * sizeof(Member)));
SetMembersPointer(m);
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wclass-memaccess"
std::memcpy(m, members, count * sizeof(Member));
+#pragma GCC diagnostic pop
}
else
SetMembersPointer(0);
diff --git a/package.json b/package.json
index 843463d7..cc6087a5 100644
Binary files a/package.json and b/package.json differ

11
build.sh Executable file
View File

@ -0,0 +1,11 @@
#!/bin/bash
source_dir=$1
build_dir=$2
tag=#3
cmake --build $build_dir -- -j
cmake --build $build_dir --target package -- -j
cp $build_dir/*rpm $source_dir/_tmp/packages 2>/dev/null || cp $build_dir/*deb $source_dir/_tmp/packages 2>/dev/null

136
build_all.py Normal file
View File

@ -0,0 +1,136 @@
import os
import subprocess
from concurrent.futures import ThreadPoolExecutor, as_completed
from pydoc import doc
# Configuration
ROOT_DIR = "./os"
MAX_WORKERS = 8 # Maximum parallel jobs for build docker image and configure project
MAX_WORKERS_COMPILE = 2 # number of compilation jobs t run
def find_dockerfiles(root_dir):
"""Recursively find all Dockerfiles in the given directory."""
dockerfiles = []
for dirpath, _, filenames in os.walk(root_dir):
for filename in filenames:
if filename == "Dockerfile":
dockerfiles.append(os.path.join(dirpath, filename))
return dockerfiles
def tags_from_path(dockerfile):
dir_path = os.path.dirname(dockerfile)
tag = dir_path.replace(ROOT_DIR + "/", "").replace(os.path.sep, "_")
return dir_path, tag
def build_docker_image(dockerfile):
"""Build a Docker image for the given Dockerfile."""
dir_path, tag = tags_from_path(dockerfile)
print(f"Starting build image step for {tag} (directory: {dir_path})...")
try:
log_file = f"_tmp/logs/{tag}/build_docker_image.log"
os.makedirs(os.path.dirname(log_file), exist_ok=True)
with open(log_file, "w") as log:
result = subprocess.run(
["docker", "build", "-t", tag, dir_path],
stdout=log,
stderr=subprocess.STDOUT,
check=True
)
return f"Successfully built {tag}"
except subprocess.CalledProcessError:
print(f"Failed to build {tag}. Check {log_file} for details.")
return f"Failed to build {tag}"
in_image_source_dir = "/home/rublon-ssh"
in_image_build_dir = "/home/build"
def configure_rublon(dockerfile):
"""Build a Docker image for the given Dockerfile."""
dir_path, tag = tags_from_path(dockerfile)
print(f"Starting configure step for {tag} (directory: {dir_path})...")
try:
log_file = f"_tmp/logs/{tag}/configure_rublon_image.log"
build_dir = f"_tmp/builds/{tag}"
os.makedirs(os.path.dirname(log_file), exist_ok=True)
os.makedirs(os.path.dirname(build_dir), exist_ok=True)
with open(log_file, "w") as log:
result = subprocess.run(
# $tag /bin/bash /home/rublon-ssh/configure.sh $tag
["docker", "run",
"-v", f"./:{in_image_source_dir}",
"-v", f"./{build_dir}:{in_image_build_dir}",
tag,
f"{in_image_source_dir}/configure.sh", in_image_source_dir, in_image_build_dir
],
stdout=log,
stderr=subprocess.STDOUT,
check=True
)
return f"Successfully built {tag}"
except subprocess.CalledProcessError:
print(f"Failed to build {tag}. Check {log_file} for details.")
return f"Failed to build {tag}"
def build_rublon(dockerfile):
"""Build a Docker image for the given Dockerfile."""
dir_path, tag = tags_from_path(dockerfile)
print(f"Starting build for {tag} (directory: {dir_path})...")
try:
log_file = f"_tmp/logs/{tag}/compile_rublon_image.log"
build_dir = f"_tmp/builds/{tag}"
packages_dir = "_tmp/packages/"
os.makedirs(os.path.dirname(log_file), exist_ok=True)
os.makedirs(os.path.dirname(build_dir), exist_ok=True)
os.makedirs(os.path.dirname(packages_dir), exist_ok=True)
with open(log_file, "w") as log:
result = subprocess.run(
# $tag /bin/bash /home/rublon-ssh/configure.sh $tag
["docker", "run",
"-v", f"./:{in_image_source_dir}",
"-v", f"./{build_dir}:{in_image_build_dir}",
tag,
f"{in_image_source_dir}/build.sh", in_image_source_dir, in_image_build_dir, tag
],
stdout=log,
stderr=subprocess.STDOUT,
check=True
)
return f"Successfully built {tag}"
except subprocess.CalledProcessError:
print(f"Failed to build {tag}. Check {log_file} for details.")
return f"Failed to build {tag}"
def run_parralel(num, job, name, dockerfiles):
# Use ThreadPoolExecutor for parallel builds
with ThreadPoolExecutor(max_workers=num) as executor:
future_to_dockerfile = {executor.submit(job, df): df for df in dockerfiles}
for future in as_completed(future_to_dockerfile):
dockerfile = future_to_dockerfile[future]
try:
result = future.result()
print(result)
except Exception as e:
print(f"Job {name} failed for {dockerfile}: {e}")
def main():
# Find all Dockerfiles
dockerfiles = find_dockerfiles(ROOT_DIR)
if not dockerfiles:
print("No Dockerfiles found.")
return
run_parralel(MAX_WORKERS, build_docker_image, "Docker Image Build", dockerfiles)
run_parralel(MAX_WORKERS, configure_rublon, "Configuring project", dockerfiles)
run_parralel(MAX_WORKERS_COMPILE, build_rublon, "Building project", dockerfiles)
print("All Docker builds completed.")
if __name__ == "__main__":
main()

View File

@ -1,9 +0,0 @@
#!/bin/bash
home_dir=$PWD
echo $home_dir
find . -type f -name Dockerfile | while read -r file_path; do
dir_path=$(dirname "$file_path")
file_name=$(echo $dir_path | cut -d'/' -f3- | sed 's|/|_|g')
docker build -t "$file_name" $dir_path
docker run -v `pwd`:/home/rublon-ssh/ $file_name /bin/bash /home/rublon-ssh/build_project.sh $file_name
done

View File

@ -1,9 +0,0 @@
#!/bin/bash
cmake -B rublon_ssh-build /home/rublon-ssh/
cmake --build rublon_ssh-build/
cmake --build rublon_ssh-build/ --target package -- -j
if [ ! -d /home/rublon-ssh/$1_packages ]; then
mkdir /home/rublon-ssh/$1_packages
fi
cp rublon_ssh-build/*rpm /home/rublon-ssh/$1_packages 2>/dev/null || cp rublon_ssh-build/*deb /home/rublon-ssh/$1_packages 2>/dev/null

7
configure.sh Executable file
View File

@ -0,0 +1,7 @@
#!/bin/bash
source_dir=$1
build_dir=$2
rm -Rf $build_dir || true
cmake -B $build_dir -DCMAKE_BUILD_TYPE=Release $source_dir

31
helpers/centos-base.repo Normal file
View File

@ -0,0 +1,31 @@
#####################################################################
# CentOS-Base.repo
#
# The mirror system uses the connecting IP address of the client and the
# update status of each mirror to pick mirrors that are updated to and
# geographically close to the client. You should use this for CentOS updates
# unless you are manually picking other mirrors.
#
# If the mirrorlist= does not work for you, as a fall back you can try the
# remarked out baseurl= line instead.
#
#
[centosApp]
name=CentOSApp-9
baseurl=https://yum.oracle.com/repo/OracleLinux/OL8/appstream/x86_64/
enabled=1
gpgcheck=0
gpgkey=http://mirror.centos.org/centos/8/os/x86_64/RPM-GPG-KEY-CentOS-8
[centosApp2]
name=CentOSApp-8
baseurl=https://yum.oracle.com/repo/OracleLinux/OL8/baseos/latest/x86_64/
enabled=1
gpgcheck=0
gpgkey=http://mirror.centos.org/centos/8/os/x86_64/RPM-GPG-KEY-CentOS-8
#[centosBase]
#name=CentOSBase-9
#baseurl=https://mirror.stream.centos.org/9-stream/BaseOS/x86_64/os/
#enabled=1
#gpgcheck=0
#gpgkey=http://mirror.centos.org/centos/8/os/x86_64/RPM-GPG-KEY-CentOS-8
#####################################################################

View File

@ -0,0 +1,31 @@
#####################################################################
# CentOS-Base.repo
#
# The mirror system uses the connecting IP address of the client and the
# update status of each mirror to pick mirrors that are updated to and
# geographically close to the client. You should use this for CentOS updates
# unless you are manually picking other mirrors.
#
# If the mirrorlist= does not work for you, as a fall back you can try the
# remarked out baseurl= line instead.
#
#
[centosApp]
name=CentOSApp-9
baseurl=https://mirror.stream.centos.org/9-stream/AppStream/x86_64/os/
enabled=1
gpgcheck=0
gpgkey=http://mirror.centos.org/centos/8/os/x86_64/RPM-GPG-KEY-CentOS-8
[centosApp2]
name=CentOSAppBase-9
baseurl=https://mirror.stream.centos.org/9-stream/BaseOS/x86_64/os/
enabled=1
gpgcheck=0
gpgkey=http://mirror.centos.org/centos/8/os/x86_64/RPM-GPG-KEY-CentOS-8
#[centosBase]
#name=CentOSBase-9
#baseurl=https://mirror.stream.centos.org/9-stream/BaseOS/x86_64/os/
#enabled=1
#gpgcheck=0
#gpgkey=http://mirror.centos.org/centos/8/os/x86_64/RPM-GPG-KEY-CentOS-8
#####################################################################

50
os/alma/8/Vagrantfile vendored
View File

@ -23,44 +23,36 @@ Vagrant.configure("2") do |config|
config.vm.synced_folder "../../..", "/home/vagrant/Rublon-Linux"
config.vm.provider "virtualbox" do |vb|
vb.memory = 8024
# Display the VirtualBox GUI when booting the machine
vb.gui = false
# Fix for 'SSH auth method: Private key' stuck
vb.customize ["modifyvm", :id, "--cableconnected1", "on"]
vb.gui = false
vb.memory = 2048
vb.cpus = 2
# Fix for 'SSH auth method: Private key' stuck
vb.customize ["modifyvm", :id, "--cableconnected1", "on"]
end
# Enable provisioning with a shell script. Additional provisioners such as
# Ansible, Chef, Docker, Puppet and Salt are also available. Please see the
# documentation for more information about their specific syntax and use.
config.vm.provision "shell", inline: <<-SHELL
export BASE=/home/vagrant/Rublon-Linux
export DISTRO=alma08
export BUILDDIR=${BASE}/${DISTRO}
export BASE=/home/vagrant/Rublon-Linux
export DISTRO=alma08
export BUILDDIR=/home/vagrant/build
yum update
yum install -y --nogpgcheck gcc wget openssl-devel openssh-server libcurl-devel pam-devel git cmake policycoreutils-devel checkpolicy gcc-c++ rpm-build libubsan libasan redhat-lsb-core
# get dependencies
mkdir ${BUILDDIR} -p; cd ${BUILDDIR}
git clone --recurse-submodules https://github.com/socketio/socket.io-client-cpp.git
mkdir socket.io-client-cpp/build_alma; cd socket.io-client-cpp/build_alma
cmake -DCMAKE_POSITION_INDEPENDENT_CODE=ON -DCMAKE_BUILD_TYPE=Release ..
cmake --build . --target install
#handle semodule
wget https://repo.almalinux.org/almalinux/8/devel/x86_64/os/Packages/rapidjson-devel-1.1.0-3.module_el8.8.0%2B3567%2B56a616e4.noarch.rpm
rpm -i rapidjson*
# Build project
cd ${BUILDDIR}
cmake -B rublon_ssh-build ..
cmake --build rublon_ssh-build/ -- -j
cmake --build rublon_ssh-build/ --target package -- -j
yum install -y --nogpgcheck gcc gcc-c++ openssl-devel openssh-server libcurl-devel pam-devel cmake policycoreutils-devel checkpolicy rpm-build redhat-lsb-core
# remove old build if exists
rm ${BUILDDIR} -Rf || true
# build package
cmake -B ${BUILDDIR} ${BASE}
cmake --build ${BUILDDIR} -j$(nproc)
cmake --build ${BUILDDIR} --target package -j$(nproc)
useradd -s /bin/bash -m bwi
echo "bwi:bwi"|chpasswd
cd ./rublon_ssh-build
yum install -y rublon*.rpm
yum install -y ${BUILDDIR}/rublon*.rpm
SHELL
end

46
os/alma/9/Vagrantfile vendored
View File

@ -23,41 +23,35 @@ Vagrant.configure("2") do |config|
config.vm.synced_folder "../../..", "/home/vagrant/Rublon-Linux"
config.vm.provider "virtualbox" do |vb|
vb.memory = 8024
vb.cpus = 4
# Display the VirtualBox GUI when booting the machine
vb.gui = false
# Fix for 'SSH auth method: Private key' stuck
vb.customize ["modifyvm", :id, "--cableconnected1", "on"]
vb.gui = false
vb.memory = 2048
vb.cpus = 2
# Fix for 'SSH auth method: Private key' stuck
vb.customize ["modifyvm", :id, "--cableconnected1", "on"]
end
# Enable provisioning with a shell script. Additional provisioners such as
# Ansible, Chef, Docker, Puppet and Salt are also available. Please see the
# documentation for more information about their specific syntax and use.
config.vm.provision "shell", inline: <<-SHELL
export BASE=/home/vagrant/Rublon-Linux
export DISTRO=alma09
export BUILDDIR=${BASE}/${DISTRO}
export BASE=/home/vagrant/Rublon-Linux
export DISTRO=alma09
export BUILDDIR=/home/vagrant/build
yum update
yum install -y --nogpgcheck gcc wget openssl-devel openssh-server libcurl-devel pam-devel git cmake policycoreutils-devel checkpolicy gcc-c++ rpm-build*
yum install -y --nogpgcheck gcc gcc-c++ openssl-devel openssh-server libcurl-devel pam-devel cmake policycoreutils-devel checkpolicy rpm-build*
cp ${BASE}/helpers/centos-base_9.repo /etc/yum.repos.d/centos-base_9.repo
# get dependencies
mkdir ${BUILDDIR} -p; cd ${BUILDDIR}
git clone --recurse-submodules https://github.com/socketio/socket.io-client-cpp.git
mkdir socket.io-client-cpp/build_alma; cd socket.io-client-cpp/build_alma
cmake -DCMAKE_POSITION_INDEPENDENT_CODE=ON -DCMAKE_BUILD_TYPE=Release ..
cmake --build . --target install
# remove old build if exists
rm ${BUILDDIR} -Rf || true
# build package
cmake -B ${BUILDDIR} ${BASE}
cmake --build ${BUILDDIR} -j$(nproc)
cmake --build ${BUILDDIR} --target package -j$(nproc)
#handle semodule
wget https://repo.almalinux.org/almalinux/9/devel/x86_64/os/Packages/rapidjson-devel-1.1.0-19.el9.x86_64.rpm
rpm -i ./rapid*
# Build project
cd ${BUILDDIR}
cmake -B rublon_ssh-build ..
cmake --build rublon_ssh-build/ -- -j
cmake --build rublon_ssh-build/ --target package -- -j
yum install -y ./rublon_ssh-build/rublon*
yum install -y ${BUILDDIR}/rublon*
useradd -s /bin/bash -m bwi
echo "bwi:bwi"|chpasswd
SHELL

View File

@ -1,6 +1,7 @@
FROM carterjones/centos-stream9
RUN yum update && yum install -y gcc \
RUN yum -y update && yum install -y \
gcc gcc-c++ \
openssl-devel \
libcurl-devel \
pam-devel \
@ -8,8 +9,8 @@ RUN yum update && yum install -y gcc \
policycoreutils-devel \
checkpolicy \
rpm-build \
openssh \
gcc-c++
openssh
WORKDIR /home/Rublon-Linux/

View File

@ -35,27 +35,24 @@ Vagrant.configure("2") do |config|
# Ansible, Chef, Docker, Puppet and Salt are also available. Please see the
# documentation for more information about their specific syntax and use.
config.vm.provision "shell", inline: <<-SHELL
export BASE=/home/vagrant/Rublon-Linux
export DISTRO=centos09
export BUILDDIR=${BASE}/${DISTRO}
export BASE=/home/vagrant/Rublon-Linux
export DISTRO=centos09
export BUILDDIR=/home/vagrant/${DISTRO}
yum update
yum install -y gcc openssl-devel libcurl-devel pam-devel git rapidjson-devel cmake policycoreutils-devel checkpolicy rpm-build openssh
yum install -y gcc gcc-c++ openssl-devel libcurl-devel pam-devel cmake policycoreutils-devel checkpolicy rpm-build openssh
# get dependencies
mkdir ${BUILDDIR} -p; cd ${BUILDDIR}
git clone --recurse-submodules https://github.com/socketio/socket.io-client-cpp.git
mkdir socket.io-client-cpp/build; cd socket.io-client-cpp/build
cmake -DCMAKE_POSITION_INDEPENDENT_CODE=ON -DCMAKE_BUILD_TYPE=Release ..
cmake --build . --target install
# remove old build if exists
rm ${BUILDDIR} -Rf || true
# build package
cmake -B ${BUILDDIR} ${BASE}
cmake --build ${BUILDDIR} -j$(nproc)y
cmake --build ${BUILDDIR} --target package -j$(nproc)
# Build project
cd ${BUILDDIR}
cmake -B rublon_ssh-build ..
cmake --build rublon_ssh-build -- -j
cmake --build rublon_ssh-build --target package -- -j
useradd -s /bin/bash -m bwi
echo "bwi:bwi"|chpasswd
sudo yum install -y ./rublon_ssh-build/rublon*.rpm
sudo yum install -y ${BUILDDIR}/rublon*.rpm
SHELL
end

View File

@ -1,14 +1,12 @@
FROM debian:11
ENV DEBIAN_FRONTEND=noniteracactive
RUN apt update && apt install -y gcc \
g++ \
RUN apt update && apt install -y \
build-essential \
openssh-server \
libcurl4-openssl-dev \
libpam0g-dev \
libssl-dev \
cmake \
git \
file
WORKDIR /home/Rublon-Linux/

View File

@ -22,50 +22,43 @@ Vagrant.configure("2") do |config|
# argument is a set of non-required options.
config.vm.synced_folder "../../..", "/home/vagrant/Rublon-Linux"
config.vm.provider "virtualbox" do |vb|
vb.memory = 4048
vb.cpus = 4
# Display the VirtualBox GUI when booting the machine
vb.gui = false
# Fix for 'SSH auth method: Private key' stuck
vb.customize ["modifyvm", :id, "--cableconnected1", "on"]
end
config.vm.provider "virtualbox" do |vb|
vb.gui = false
vb.memory = 2048
vb.cpus = 2
# Fix for 'SSH auth method: Private key' stuck
vb.customize ["modifyvm", :id, "--cableconnected1", "on"]
end
# Enable provisioning with a shell script. Additional provisioners such as
# Ansible, Chef, Docker, Puppet and Salt are also available. Please see the
# documentation for more information about their specific syntax and use.
config.vm.provision "shell", inline: <<-SHELL
export BASE=/home/vagrant/Rublon-Linux
export DISTRO=debian11
export BUILDDIR=${BASE}/${DISTRO}
DEBIAN_FRONTEND=noniteracactive\
apt-get update && apt-get install -y \
gcc \
build-essential \
openssh-server \
libcurl4-openssl-dev \
libpam0g-dev \
libssl-dev \
git \
rapidjson-dev \
cmake
export BASE=/home/vagrant/Rublon-Linux
export DISTRO=debian11
export BUILDDIR=/home/vagrant/build
# get dependencies
mkdir ${BUILDDIR} -p; cd ${BUILDDIR}
git clone --recurse-submodules https://github.com/socketio/socket.io-client-cpp.git
cmake -B socket.io-build -DCMAKE_POSITION_INDEPENDENT_CODE=ON -DCMAKE_BUILD_TYPE=Release socket.io-client-cpp
cmake --build socket.io-build --target install -- -j
DEBIAN_FRONTEND=noniteracactive \
apt-get update && apt-get install -y \
build-essential \
openssh-server \
libcurl4-openssl-dev \
libpam0g-dev \
libssl-dev \
cmake
# Build project
cd ${BUILDDIR}
cmake -B rublon_ssh-build ..
cmake --build rublon_ssh-build -- -j
cmake --build rublon_ssh-build --target package -- -j
# Register Rublon pam
useradd -s /bin/bash -m bwi
echo "bwi:bwi"|chpasswd
sudo dpkg -i ./rublon_ssh-build/rublon*
# remove old build if exists
rm ${BUILDDIR} -Rf || true
# build package
cmake -B ${BUILDDIR} ${BASE}
cmake --build ${BUILDDIR} -j$(nproc)
cmake --build ${BUILDDIR} --target package -j$(nproc)
# Register Rublon pam
useradd -s /bin/bash -m bwi
echo "bwi:bwi"|chpasswd
sudo dpkg -i ${BUILDDIR}/rublon*.deb
SHELL
end

View File

@ -1,14 +1,12 @@
FROM debian:12
ENV DEBIAN_FRONTEND=noniteracactive
RUN apt update && apt install -y gcc \
g++ \
RUN apt update && apt install -y \
build-essential \
openssh-server \
libcurl4-openssl-dev \
libpam0g-dev \
libssl-dev \
cmake \
git \
file
WORKDIR /home/Rublon-Linux/

View File

@ -23,10 +23,9 @@ Vagrant.configure("2") do |config|
config.vm.synced_folder "../../..", "/home/vagrant/Rublon-Linux"
config.vm.provider "virtualbox" do |vb|
# Display the VirtualBox GUI when booting the machine
vb.gui = false
vb.memory = 8044
vb.cpus = 4
vb.memory = 2048
vb.cpus = 2
# Fix for 'SSH auth method: Private key' stuck
vb.customize ["modifyvm", :id, "--cableconnected1", "on"]
@ -36,36 +35,30 @@ Vagrant.configure("2") do |config|
# Ansible, Chef, Docker, Puppet and Salt are also available. Please see the
# documentation for more information about their specific syntax and use.
config.vm.provision "shell", inline: <<-SHELL
export BASE=/home/vagrant/Rublon-Linux
export DISTRO=debian12
export BUILDDIR=${BASE}/${DISTRO}
DEBIAN_FRONTEND=noniteracactive\
apt-get update && apt-get install -y \
gcc \
build-essential \
openssh-server \
libcurl4-openssl-dev \
libpam0g-dev \
libssl-dev \
git \
rapidjson-dev \
cmake
# get dependencies
mkdir ${BUILDDIR} -p; cd ${BUILDDIR}
git clone --recurse-submodules https://github.com/socketio/socket.io-client-cpp.git
cmake -B socket.io-build -DCMAKE_POSITION_INDEPENDENT_CODE=ON -DCMAKE_BUILD_TYPE=Release socket.io-client-cpp
cmake --build socket.io-build --target install -- -j
export BASE=/home/vagrant/Rublon-Linux
export DISTRO=debian12
export BUILDDIR=/home/vagrant/build
# Build project
cd ${BUILDDIR}
cmake -B rublon_ssh-build ..
cmake --build rublon_ssh-build -- -j
cmake --build rublon_ssh-build --target package -- -j
# Register Rublon pam
useradd -s /bin/bash -m bwi
echo "bwi:bwi"|chpasswd
sudo dpkg -i ${BUILDDIR}/rublon_ssh-build/rublon*
DEBIAN_FRONTEND=noniteracactive \
apt-get update && apt-get install -y \
build-essential \
openssh-server \
libcurl4-openssl-dev \
libpam0g-dev \
libssl-dev \
cmake
# remove old build if exists
rm ${BUILDDIR} -Rf || true
# build package
cmake -B ${BUILDDIR} ${BASE}
cmake --build ${BUILDDIR} -j$(nproc)
cmake --build ${BUILDDIR} --target package -j$(nproc)
# Register Rublon pam
useradd -s /bin/bash -m bwi
echo "bwi:bwi"|chpasswd
sudo dpkg -i ${BUILDDIR}/rublon*.deb
SHELL
end

View File

@ -37,35 +37,29 @@ Vagrant.configure("2") do |config|
config.vm.provision "shell", inline: <<-SHELL
export BASE=/home/vagrant/Rublon-Linux
export DISTRO=opensuse15
export BUILDDIR=${BASE}/${DISTRO}
export BUILDDIR=/home/vagrant/${DISTRO}
zypper --non-interactive install -y \
gcc \
gcc-c++ \
openssh-server \
libcurl-devel \
libpamtest-devel \
git \
rapidjson-devel \
cmake \
pam-devel \
openssl-devel \
rpm-build
# get dependencies
mkdir ${BUILDDIR} -p;
git clone --recurse-submodules https://github.com/socketio/socket.io-client-cpp.git
cmake -B socket.io-build -DCMAKE_POSITION_INDEPENDENT_CODE=ON -DCMAKE_BUILD_TYPE=Release socket.io-client-cpp
cmake --build socket.io-build --target install -- -j
# Build project
cd ${BUILDDIR}
cmake -B rublon_ssh-build ..
cmake --build rublon_ssh-build -- -j
cmake --build rublon_ssh-build --target package -- -j
# Register Rublon pam
useradd -s /bin/bash -m bwi
echo "bwi:bwi"|chpasswd
sudo zypper --no-gpg-checks install -y ${BUILDDIR}/rublon_ssh-build/rublon*
# remove old build if exists
rm ${BUILDDIR} -Rf || true
# build package
cmake -B ${BUILDDIR} ${BASE}
cmake --build ${BUILDDIR} -j$(nproc)
cmake --build ${BUILDDIR} --target package -j$(nproc)
# Register Rublon pam
useradd -s /bin/bash -m bwi
echo "bwi:bwi"|chpasswd
sudo zypper --no-gpg-checks install -y ${BUILDDIR}/rublon*
SHELL
end

View File

@ -9,7 +9,6 @@ RUN yum update -y && yum install -y gcc \
openssh-server \
gcc-c++ \
wget
RUN wget https://yum.oracle.com/repo/OracleLinux/OL8/baseos/latest/x86_64/getPackage/pam-1.3.1-34.0.1.el8_10.x86_64.rpm \
https://yum.oracle.com/repo/OracleLinux/OL8/baseos/latest/x86_64/getPackage/pam-devel-1.3.1-34.0.1.el8_10.x86_64.rpm
RUN wget https://yum.oracle.com/repo/OracleLinux/OL8/baseos/latest/x86_64/getPackage/pam-devel-1.3.1-34.0.1.el8_10.x86_64.rpm
RUN rpm -Uvh pam*

53
os/rhel/8/Vagrantfile vendored
View File

@ -24,39 +24,40 @@ Vagrant.configure("2") do |config|
# config.vm.synced_folder "../../../../socket.io", "/home/vagrant/socket.io"
config.vm.provider "virtualbox" do |vb|
vb.memory = 8024
# Display the VirtualBox GUI when booting the machine
vb.gui = false
# Fix for 'SSH auth method: Private key' stuck
vb.customize ["modifyvm", :id, "--cableconnected1", "on"]
vb.gui = false
vb.memory = 2048
vb.cpus = 2
# Fix for 'SSH auth method: Private key' stuck
vb.customize ["modifyvm", :id, "--cableconnected1", "on"]
end
# Enable provisioning with a shell script. Additional provisioners such as
# Ansible, Chef, Docker, Puppet and Salt are also available. Please see the
# documentation for more information about their specific syntax and use.
config.vm.provision "shell", inline: <<-SHELL
export BASE=/home/vagrant/Rublon-Linux
export DISTRO=rhel8
export BUILDDIR=${BASE}/${DISTRO}
cp ${BASE}/helpers/centos-base.repo /etc/yum.repos.d/
yum install -y openssl-devel libcurl systemd-pam git rapidjson-devel cmake pam-devel libcurl-devel libasan libubsan rpm-build redhat-lsb-core
# get dependencies
mkdir ${BUILDDIR} -p; cd ${BUILDDIR}
git clone --recurse-submodules https://github.com/socketio/socket.io-client-cpp.git
cmake -B socket.io-build -DCMAKE_POSITION_INDEPENDENT_CODE=ON -DCMAKE_BUILD_TYPE=Release socket.io-client-cpp
cmake --build socket.io-build --target install -- -j
useradd -s /bin/bash -m bwi
echo "bwi:bwi"|chpasswd
# Build project
cd ${BUILDDIR}
cmake -B rublon_ssh-build ..
cmake --build rublon_ssh-build -- -j
cmake --build rublon_ssh-build --target package -- -j
# Register Rublon pam
yum -y install ./rublon_ssh-build/rublon-ssh*.el8.rpm
export BASE=/home/vagrant/Rublon-Linux
export DISTRO=rhel8
export BUILDDIR=/home/vagrant/build
cp ${BASE}/helpers/centos-base.repo /etc/yum.repos.d/
yum update
yum install -y openssl-devel libcurl systemd-pam cmake pam-devel libcurl-devel rpm-build redhat-lsb-core
# remove old build if exists
rm ${BUILDDIR} -Rf || true
# build package
cmake -B ${BUILDDIR} ${BASE}
cmake --build ${BUILDDIR} -j$(nproc)
cmake --build ${BUILDDIR} --target package -j$(nproc)
SHELL
# Register Rublon pam
yum -y install ${BUILDDIR}/rublon-ssh*.el8.rpm
useradd -s /bin/bash -m bwi
echo "bwi:bwi"|chpasswd
SHELL
end

49
os/rhel/9/Vagrantfile vendored
View File

@ -23,41 +23,38 @@ Vagrant.configure("2") do |config|
config.vm.synced_folder "../../..", "/home/vagrant/Rublon-Linux"
config.vm.provider "virtualbox" do |vb|
vb.memory = 6024
# Display the VirtualBox GUI when booting the machine
vb.gui = false
# Fix for 'SSH auth method: Private key' stuck
vb.customize ["modifyvm", :id, "--cableconnected1", "on"]
vb.gui = false
vb.memory = 2048
vb.cpus = 2
# Fix for 'SSH auth method: Private key' stuck
vb.customize ["modifyvm", :id, "--cableconnected1", "on"]
end
# Enable provisioning with a shell script. Additional provisioners such as
# Ansible, Chef, Docker, Puppet and Salt are also available. Please see the
# documentation for more information about their specific syntax and use.
config.vm.provision "shell", inline: <<-SHELL
export BASE=/home/vagrant/Rublon-Linux
export DISTRO=rhel9
export BUILDDIR=${BASE}/${DISTRO}
cp ${BASE}/helpers/centos-base_9.repo /etc/yum.repos.d/centos-base_9.repo
export BASE=/home/vagrant/Rublon-Linux
export DISTRO=rhel9
export BUILDDIR=/home/vagrant/build
cp ${BASE}/helpers/centos-base_9.repo /etc/yum.repos.d/centos-base_9.repo
yum update
yum install -y gcc openssl-devel openssh libcurl systemd-pam git rapidjson-devel cmake rpm-build lsb-release pam-devel libcurl-devel
useradd -s /bin/bash -m bwi
echo "bwi:bwi"|chpasswd
# get dependencies
mkdir ${BUILDDIR} -p; cd ${BUILDDIR}
git clone --recurse-submodules https://github.com/socketio/socket.io-client-cpp.git
cmake -B socket.io-build -DCMAKE_POSITION_INDEPENDENT_CODE=ON -DCMAKE_BUILD_TYPE=Release socket.io-client-cpp
cmake --build socket.io-build --target install -- -j
yum install -y gcc openssl-devel openssh libcurl systemd-pam cmake rpm-build lsb-release pam-devel libcurl-devel
# Build project
cd ${BUILDDIR}
cmake -B rublon_ssh-build ..
cmake --build rublon_ssh-build -- -j
cmake --build rublon_ssh-build --target package -- -j
# Register Rublon pam
yum -y install ./rublon_ssh-build/rublon*.rpm
# remove old build if exists
rm ${BUILDDIR} -Rf || true
# build package
cmake -B ${BUILDDIR} ${BASE}
cmake --build ${BUILDDIR} -j$(nproc)
cmake --build ${BUILDDIR} --target package -j$(nproc)
# Register Rublon pam
useradd -s /bin/bash -m bwi
echo "bwi:bwi"|chpasswd
yum -y install ${BUILDDIR}/rublon*.rpm
SHELL
end

View File

@ -23,37 +23,36 @@ Vagrant.configure("2") do |config|
# argument is a set of non-required options.
config.vm.provider "virtualbox" do |vb|
vb.memory = 8024
# Display the VirtualBox GUI when booting the machine
vb.gui = false
# Fix for 'SSH auth method: Private key' stuck
vb.customize ["modifyvm", :id, "--cableconnected1", "on"]
vb.gui = false
vb.memory = 2048
vb.cpus = 2
# Fix for 'SSH auth method: Private key' stuck
vb.customize ["modifyvm", :id, "--cableconnected1", "on"]
end
# Enable provisioning with a shell script. Additional provisioners such as
# Ansible, Chef, Docker, Puppet and Salt are also available. Please see the
# documentation for more information about their specific syntax and use.
config.vm.provision "shell", inline: <<-SHELL
export BASE=/home/vagrant/Rublon-Linux
export DISTRO=rocky9
export BUILDDIR=${BASE}/${DISTRO}
yum install -y epel-release
yum install -y gcc openssl-devel systemd-pam git cmake gcc-c++ rapidjson-devel wget pam-devel rpm-build libcurl-devel policycoreutils-python-utils
# get dependencies
mkdir ${BUILDDIR} -p; cd ${BUILDDIR}
git clone --recurse-submodules https://github.com/socketio/socket.io-client-cpp.git
cmake -B socket.io-build -DCMAKE_POSITION_INDEPENDENT_CODE=ON -DCMAKE_BUILD_TYPE=Release socket.io-client-cpp
cmake --build socket.io-build --target install -- -j
export BASE=/home/vagrant/Rublon-Linux
export DISTRO=rocky9
export BUILDDIR=/home/vagrant/build
yum install -y epel-release
yum install -y gcc gcc-c++ openssl-devel systemd-pam cmake pam-devel rpm-build libcurl-devel policycoreutils-python-utils
# Build project
cd ${BUILDDIR}
cmake -B rublon_ssh-build ..
cmake --build rublon_ssh-build -- -j
cmake --build rublon_ssh-build --target package -- -j
useradd -s /bin/bash -m bwi
echo "bwi:bwi"|chpasswd
sudo yum install -y ./rublon_ssh-build/rublon*.rpm
# remove old build if exists
rm ${BUILDDIR} -Rf || true
# build package
cmake -B ${BUILDDIR} ${BASE}
cmake --build ${BUILDDIR} -j$(nproc)
cmake --build ${BUILDDIR} --target package -j$(nproc)
useradd -s /bin/bash -m bwi
echo "bwi:bwi"|chpasswd
sudo yum install -y ./rublon_ssh-build/rublon*.rpm
SHELL
end

View File

@ -1,7 +1,6 @@
FROM ubuntu:20.04
ENV DEBIAN_FRONTEND=noniteracactive
RUN apt update && apt install -y gcc \
g++ \
RUN apt update && apt install -y \
build-essential \
openssh-server \
libcurl4-openssl-dev \

View File

@ -23,50 +23,42 @@ Vagrant.configure("2") do |config|
config.vm.synced_folder "../../..", "/home/vagrant/Rublon-Linux"
config.vm.provider "virtualbox" do |vb|
vb.memory = 8060
# Display the VirtualBox GUI when booting the machine
vb.gui = false
# Fix for 'SSH auth method: Private key' stuck
vb.customize ["modifyvm", :id, "--cableconnected1", "on"]
vb.gui = false
vb.memory = 2048
vb.cpus = 2
# Fix for 'SSH auth method: Private key' stuck
vb.customize ["modifyvm", :id, "--cableconnected1", "on"]
end
# Enable provisioning with a shell script. Additional provisioners such as
# Ansible, Chef, Docker, Puppet and Salt are also available. Please see the
# documentation for more information about their specific syntax and use.
config.vm.provision "shell", inline: <<-SHELL
export BASE=/home/vagrant/Rublon-Linux
export DISTRO=ubuntu2004
export BUILDDIR=${BASE}/${DISTRO}
DEBIAN_FRONTEND=noniteracactive\
apt-get update && apt-get install -y \
gcc \
g++ \
build-essential \
openssh-server \
libcurl4-openssl-dev \
libpam0g-dev \
libssl-dev \
git \
rapidjson-dev \
cmake
export BASE=/home/vagrant/Rublon-Linux
export DISTRO=ubuntu2004
export BUILDDIR=/home/vagrant/build
DEBIAN_FRONTEND=noniteracactive \
apt-get update && apt-get install -y \
build-essential \
openssh-server \
libcurl4-openssl-dev \
libpam0g-dev \
libssl-dev \
cmake
# get dependencies
mkdir ${BUILDDIR} -p; cd ${BUILDDIR}
git clone --recurse-submodules https://github.com/socketio/socket.io-client-cpp.git
cmake -B socket.io-build -DCMAKE_POSITION_INDEPENDENT_CODE=ON -DCMAKE_BUILD_TYPE=Release socket.io-client-cpp
cmake --build socket.io-build --target install -- -j
ln -s /usr/bin/make /usr/bin/gmake
# Build project
cd ${BUILDDIR}
cmake -B rublon_ssh-build ..
cmake --build rublon_ssh-build -- -j
cmake --build rublon_ssh-build --target package -- -j
# Register Rublon pam
useradd -s /bin/bash -m bwi
echo "bwi:bwi"|chpasswd
sudo dpkg -i ${BUILDDIR}/rublon_ssh-build/rublon*.deb
SHELL
# remove old build if exists
rm ${BUILDDIR} -Rf || true
# build package
cmake -B ${BUILDDIR} ${BASE}
cmake --build ${BUILDDIR} -j$(nproc)
cmake --build ${BUILDDIR} --target package -j$(nproc)
# Register Rublon pam
useradd -s /bin/bash -m bwi
echo "bwi:bwi"|chpasswd
sudo dpkg -i ${BUILDDIR}/rublon*.deb
SHELL
end

View File

@ -1,7 +1,6 @@
FROM ubuntu:22.04
ENV DEBIAN_FRONTEND=noniteracactive
RUN apt update && apt install -y gcc \
g++ \
RUN apt update && apt install -y \
build-essential \
openssh-server \
libcurl4-openssl-dev \

View File

@ -23,43 +23,42 @@ Vagrant.configure("2") do |config|
config.vm.synced_folder "../../..", "/home/vagrant/Rublon-Linux"
config.vm.provider "virtualbox" do |vb|
vb.memory = 4000
# Display the VirtualBox GUI when booting the machine
vb.gui = false
# Fix for 'SSH auth method: Private key' stuck
vb.customize ["modifyvm", :id, "--cableconnected1", "on"]
vb.gui = false
vb.memory = 2048
vb.cpus = 2
# Fix for 'SSH auth method: Private key' stuck
vb.customize ["modifyvm", :id, "--cableconnected1", "on"]
end
# Enable provisioning with a shell script. Additional provisioners such as
# Ansible, Chef, Docker, Puppet and Salt are also available. Please see the
# documentation for more information about their specific syntax and use.
config.vm.provision "shell", inline: <<-SHELL
export BASE=/home/vagrant/Rublon-Linux
export DISTRO=ubuntu2204
export BUILDDIR=${BASE}/${DISTRO}
DEBIAN_FRONTEND=noniteracactive\
apt-get update && apt-get install -y \
gcc \
build-essential \
openssh-server \
libcurl4-openssl-dev \
libpam0g-dev \
libssl-dev \
git \
rapidjson-dev \
libwebsockets-dev \
cmake
export BASE=/home/vagrant/Rublon-Linux
export DISTRO=ubuntu2204
export BUILDDIR=/home/vagrant/build
# get dependencies
mkdir ${BUILDDIR} -p; cd ${BUILDDIR}
cmake -B rublon_ssh-build ..
cmake --build rublon_ssh-build -- -j
cmake --build rublon_ssh-build --target package -- -j
# Register Rublon pam
useradd -s /bin/bash -m bwi
echo "bwi:bwi"|chpasswd
sudo dpkg -i ${BUILDDIR}/rublon_ssh-build/rublon*.deb
DEBIAN_FRONTEND=noniteracactive \
apt-get update && apt-get install -y \
build-essential \
openssh-server \
libcurl4-openssl-dev \
libpam0g-dev \
libssl-dev \
cmake
# remove old build if exists
rm ${BUILDDIR} -Rf || true
# build package
cmake -B ${BUILDDIR} ${BASE}
cmake --build ${BUILDDIR} -j$(nproc)
cmake --build ${BUILDDIR} --target package -j$(nproc)
# Register Rublon pam
useradd -s /bin/bash -m bwi
echo "bwi:bwi"|chpasswd
sudo dpkg -i ${BUILDDIR}/rublon*.deb
SHELL
end

View File

@ -1,7 +1,6 @@
FROM ubuntu:24.04
ENV DEBIAN_FRONTEND=noniteracactive
RUN apt update && apt install -y gcc \
g++ \
RUN apt update && apt install -y \
build-essential \
openssh-server \
libcurl4-openssl-dev \

View File

@ -22,48 +22,42 @@ Vagrant.configure("2") do |config|
config.vm.synced_folder "../../..", "/home/vagrant/Rublon-Linux"
config.vm.provider "virtualbox" do |vb|
vb.memory = 4000
# Display the VirtualBox GUI when booting the machine
vb.gui = false
# Fix for 'SSH auth method: Private key' stuck
vb.customize ["modifyvm", :id, "--cableconnected1", "on"]
vb.gui = false
vb.memory = 2048
vb.cpus = 2
# Fix for 'SSH auth method: Private key' stuck
vb.customize ["modifyvm", :id, "--cableconnected1", "on"]
end
# Enable provisioning with a shell script. Additional provisioners such as
# Ansible, Chef, Docker, Puppet and Salt are also available. Please see the
# documentation for more information about their specific syntax and use.
config.vm.provision "shell", inline: <<-SHELL
export BASE=/home/vagrant/Rublon-Linux
export DISTRO=ubuntu2404
export BUILDDIR=${BASE}/${DISTRO}
DEBIAN_FRONTEND=noniteracactive\
apt-get update && apt-get install -y \
gcc \
build-essential \
openssh-server \
libcurl4-openssl-dev \
libpam0g-dev \
libssl-dev \
git \
rapidjson-dev \
cmake
export BASE=/home/vagrant/Rublon-Linux
export DISTRO=ubuntu2404
export BUILDDIR=/home/vagrant/build
# get dependencies
mkdir ${BUILDDIR} -p; cd ${BUILDDIR}
git clone --recurse-submodules https://github.com/socketio/socket.io-client-cpp.git
cmake -B socket.io-build -DCMAKE_POSITION_INDEPENDENT_CODE=ON -DCMAKE_BUILD_TYPE=Release socket.io-client-cpp
cmake --build socket.io-build --target install -- -j
ln -s /usr/bin/make /usr/bin/gmake
# Build project
cd ${BUILDDIR}
cmake -B rublon_ssh-build ..
cmake --build rublon_ssh-build -- -j
cmake --build rublon_ssh-build --target package -- -j
# Register Rublon pam
useradd -s /bin/bash -m bwi
echo "bwi:bwi"|chpasswd
sudo dpkg -i ${BUILDDIR}/rublon_ssh-build/rublon*.deb
DEBIAN_FRONTEND=noniteracactive \
apt-get update && apt-get install -y \
build-essential \
openssh-server \
libcurl4-openssl-dev \
libpam0g-dev \
libssl-dev \
cmake
# remove old build if exists
rm ${BUILDDIR} -Rf || true
# build package
cmake -B ${BUILDDIR} ${BASE}
cmake --build ${BUILDDIR} -j$(nproc)
cmake --build ${BUILDDIR} --target package -j$(nproc)
# Register Rublon pam
useradd -s /bin/bash -m bwi
echo "bwi:bwi"|chpasswd
sudo dpkg -i ${BUILDDIR}/rublon*.deb
SHELL
end

View File

@ -29,7 +29,12 @@ if ( ${outOS} MATCHES "ubuntu" OR ${outOS} MATCHES "debian" )
set(CPACK_DEBIAN_PAM-DEV_PACKAGE_NAME, YES)
set(CPACK_DEB_COMPONENT_INSTALL YES)
set(CPACK_DEBIAN_PACKAGE_SHLIBDEPS YES)
set(CPACK_SOURCE_IGNORE_FILES "${CMAKE_CURRENT_SOURCE_DIR}/service/login_rublon.mod" )
list(APPEND CPACK_SOURCE_IGNORE_FILES "${CMAKE_CURRENT_SOURCE_DIR}/service/login_rublon.pp")
list(APPEND CPACK_SOURCE_IGNORE_FILES "${CMAKE_CURRENT_SOURCE_DIR}/service/login_rublon.te")
list(APPEND CPACK_SOURCE_IGNORE_FILES "${CMAKE_CURRENT_SOURCE_DIR}/service/pam_service.txt")
list(APPEND CPACK_SOURCE_IGNORE_FILES "${CMAKE_CURRENT_SOURCE_DIR}/service/rublon_veritas")
set(CPACK_SOURCE_IGNORE_FILES "${CMAKE_CURRENT_SOURCE_DIR}/service/inst_pubkey_rhel9.sh")
execute_process (
COMMAND bash -c "awk -F= '/^VERSION_ID=/{print $2}' /etc/os-release |tr -d '\n' | tr -d '\"'"
OUTPUT_VARIABLE VERSION_ID

View File

@ -1,6 +1,6 @@
UsePAM yes
ChallengeResponseAuthentication yes
LoginGraceTime 15m
ChallengeResponseAuthentication yes
AuthenticationMethods publickey,keyboard-interactive
MaxAuthTries 3
PubkeyAuthentication yes

View File

@ -1,25 +0,0 @@
#!/bin/bash
SSHD_CONF=/etc/ssh/sshd_config
SSHD_PAM_CONF=/etc/pam.d/sshd
RUBLON_SSH_CONFIG=/etc/ssh/sshd_config.d/01-rublon-ssh.conf
cp -a /usr/share/rublon/01-rublon-ssh_pubkey.conf.default $RUBLON_SSH_CONFIG
chown root:root $RUBLON_SSH_CONFIG
chmod 640 $RUBLON_SSH_CONFIG
if [ -f /etc/os-release ]
then
. /etc/os-release
fi
grep -qe 'auth requisite pam_rublon.so' $SSHD_PAM_CONF || sed -i '$aauth requisite pam_rublon.so' $SSHD_PAM_CONF
if [ ${OS} == "Ubuntu"]
then
grep -qe 'account required pam_rublon.so' $SSHD_PAM_CONF || sed -i '$aaccount required pam_rublon.so' $SSHD_PAM_CONF
fi
grep -qe '@include common-auth' $SSHD_PAM_CONF || sed -i 's/@include common-auth/#@include common-auth/' $SSHD_PAM_CONF
systemctrl restart sshd

View File

@ -3,6 +3,7 @@
RUBLON_CONFIG=/etc/rublon.config
RUBLON_SSH_CONFIG=/etc/ssh/sshd_config.d/01-rublon-ssh.conf
SSHD_PAM_CONF=/etc/pam.d/sshd
VERITAS_PATH=/usr/openv/netbackup/sec/at/bin/
if [ -f $RUBLON_CONFIG ]
then

View File

@ -1,37 +0,0 @@
#!/bin/bash
SSHD_CONF=/etc/ssh/sshd_config
SSHD_PAM_CONF=/etc/pam.d/sshd
RUBLON_SSH_CONFIG=/etc/ssh/sshd_config.d/01-rublon-ssh.conf
cp -a /usr/share/rublon/01-rublon-ssh_pubkey.conf.default $RUBLON_SSH_CONFIG
chown root:root $RUBLON_SSH_CONFIG
chmod 640 $RUBLON_SSH_CONFIG
if [ -f /etc/os-release ]
then
. /etc/os-release
fi
sed -i '/auth required pam_rublon.so/d' $SSHD_PAM_CONF
if [[ $ID == "rhel" || $ID=="alma" || $ID=="rocky" || $ID=="Centos" ]]
then
grep -qe 'auth required pam_rublon.so' $SSHD_PAM_CONF || sed -i '$aauth required pam_rublon.so' $SSHD_PAM_CONF
grep -qe '#auth substack password-auth' $SSHD_PAM_CONF || sed -i -e 's/auth substack password-auth/#auth substack password-auth/g' $SSHD_PAM_CONF
elif [ $ID = "Debian" ]
then
grep -qe 'auth requisite pam_rublon.so' $SSHD_PAM_CONF || sed -i '$aauth requisite pam_rublon.so' $SSHD_PAM_CONF
else
grep -qe 'auth requisite pam_rublon.so' $SSHD_PAM_CONF || sed -i '$aauth requisite pam_rublon.so' $SSHD_PAM_CONF
grep -qe 'account required pam_rublon.so' $SSHD_PAM_CONF || sed -i '$aaccount required pam_rublon.so' $SSHD_PAM_CONF
fi
grep -qe '#@include common-auth' $SSHD_PAM_CONF || sed -i 's/@include common-auth/#@include common-auth/' $SSHD_PAM_CONF
if [[ $ID == "rhel" || $ID=="alma" || $ID=="rocky" || $ID=="Centos" ]]
then
systemctl restart sshd
else
deb-systemd-invoke restart ssh.service
fi

17
service/inst_pubkey.sh Normal file
View File

@ -0,0 +1,17 @@
#!/bin/bash
SSHD_CONF=/etc/ssh/sshd_config
SSHD_PAM_CONF=/etc/pam.d/sshd
RUBLON_SSH_CONFIG=/etc/ssh/sshd_config.d/01-rublon-ssh.conf
cp -a /usr/share/rublon/01-rublon-ssh_pubkey.conf.default $RUBLON_SSH_CONFIG
chown root:root $RUBLON_SSH_CONFIG
chmod 640 $RUBLON_SSH_CONFIG
grep -qe 'auth required pam_rublon.so' $SSHD_PAM_CONF || sed -i '$aauth required pam_rublon.so' $SSHD_PAM_CONF
grep -qe 'account required pam_rublon.so' $SSHD_PAM_CONF || sed -i '$aaccount required pam_rublon.so' $SSHD_PAM_CONF
grep -qe '#@include \+common-auth' $SSHD_PAM_CONF || sed -i 's/@include \+common-auth/#@include common-auth/' $SSHD_PAM_CONF
deb-systemd-invoke restart ssh.service

View File

@ -0,0 +1,15 @@
#!/bin/bash
SSHD_CONF=/etc/ssh/sshd_config
SSHD_PAM_CONF=/etc/pam.d/sshd
RUBLON_SSH_CONFIG=/etc/ssh/01-rublon-ssh.conf
cp -a /usr/share/rublon/01-rublon-ssh_pubkey.conf.default $RUBLON_SSH_CONFIG
chown root:root $RUBLON_SSH_CONFIG
chmod 640 $RUBLON_SSH_CONFIG
grep -qe 'account required pam_rublon.so' $SSHD_PAM_CONF || sed -i '$aaccount required pam_rublon.so' $SSHD_PAM_CONF
grep -qe '#auth \+substack \+password-auth' $SSHD_PAM_CONF || sed -i 's/auth \+substack \+password-auth/#auth substack password-auth/' $SSHD_PAM_CONF
systemctl restart sshd

View File

@ -0,0 +1,17 @@
#!/bin/bash
SSHD_CONF=/etc/ssh/sshd_config
SSHD_PAM_CONF=/etc/pam.d/sshd
RUBLON_SSH_CONFIG=/etc/ssh/sshd_config.d/01-rublon-ssh.conf
cp -a /usr/share/rublon/01-rublon-ssh_pubkey.conf.default $RUBLON_SSH_CONFIG
chown root:root $RUBLON_SSH_CONFIG
chmod 640 $RUBLON_SSH_CONFIG
grep -qe 'auth required pam_rublon.so' $SSHD_PAM_CONF || sed -i '$aauth required pam_rublon.so' $SSHD_PAM_CONF
grep -qe 'account required pam_rublon.so' $SSHD_PAM_CONF || sed -i '$aaccount required pam_rublon.so' $SSHD_PAM_CONF
grep -qe '#auth \+substack \+password-auth' $SSHD_PAM_CONF || sed -i 's/auth \+substack \+password-auth/#auth substack password-auth/' $SSHD_PAM_CONF
systemctl restart sshd

View File

@ -1,41 +0,0 @@
#!/bin/bash
SSHD_CONF=/etc/ssh/sshd_config
SSHD_PAM_CONF=/etc/pam.d/sshd
RUBLON_CONFIG=/etc/rublon.config
RUBLON_SSH_CONFIG=/etc/ssh/sshd_config.d/01-rublon-ssh.conf
if [ ! -f $RUBLON_CONFIG ]
then
cp -a /usr/share/rublon/rublon.config.defaults $RUBLON_CONFIG
chown root:root $RUBLON_CONFIG
chmod 640 $RUBLON_CONFIG
fi
cp -a /usr/share/rublon/service/01-rublon-ssh_pubkey.conf.default $RUBLON_SSH_CONFIG
chown root:root $RUBLON_SSH_CONFIG
chmod 640 $RUBLON_SSH_CONFIG
if [ -f /etc/os-release ]
then
. /etc/os-release
fi
#if [[ $ID == "rhel" || $ID=="alma" || $ID=="rocky" ]]
#then
# cd /usr/share/rublon/service
# checkmodule -M -m -o login_rublon.mod login_rublon.te
# semodule_package -o login_rublon.pp -m login_rublon.mod
# semodule -i login_rublon.pp
#fi
grep -qe 'auth required pam_rublon.so' $SSHD_PAM_CONF || sed -i '$aauth required pam_rublon.so' $SSHD_PAM_CONF
grep -qe 'account required pam_rublon.so' $SSHD_PAM_CONF || sed -i '$aaccount required pam_rublon.so' $SSHD_PAM_CONF
grep -qe '@include common-auth' $SSHD_PAM_CONF || sed -i 's/@include common-auth/#@include common-auth/' $SSHD_PAM_CONF
if [[ $ID == "rhel" || $ID=="alma" || $ID=="rocky" ]]
then
systemctl restart sshd
else
deb-systemd-invoke restart ssh.service
fi

View File

@ -1,37 +0,0 @@
#!/bin/bash
SSHD_CONF=/etc/ssh/sshd_config
SSHD_PAM_CONF=/etc/pam.d/sshd
RUBLON_SSH_CONFIG=/etc/ssh/sshd_config.d/01-rublon-ssh.conf
cp -a /usr/share/rublon/01-rublon-ssh_pubkey.conf.default $RUBLON_SSH_CONFIG
chown root:root $RUBLON_SSH_CONFIG
chmod 640 $RUBLON_SSH_CONFIG
if [ -f /etc/os-release ]
then
. /etc/os-release
fi
sed -i '/auth required pam_rublon.so/d' $SSHD_PAM_CONF
if [[ $ID == "rhel" || $ID=="alma" || $ID=="rocky" || $ID=="Centos" ]]
then
grep -qe 'auth required pam_rublon.so' $SSHD_PAM_CONF || sed -i '$aauth required pam_rublon.so' $SSHD_PAM_CONF
grep -qe '#auth substack password-auth' $SSHD_PAM_CONF || sed -i -e 's/auth substack password-auth/#auth substack password-auth/g' $SSHD_PAM_CONF
elif [ $ID = "Debian" ]
then
grep -qe 'auth requisite pam_rublon.so' $SSHD_PAM_CONF || sed -i '$aauth requisite pam_rublon.so' $SSHD_PAM_CONF
else
grep -qe 'auth requisite pam_rublon.so' $SSHD_PAM_CONF || sed -i '$aauth requisite pam_rublon.so' $SSHD_PAM_CONF
grep -qe 'account required pam_rublon.so' $SSHD_PAM_CONF || sed -i '$aaccount required pam_rublon.so' $SSHD_PAM_CONF
fi
grep -qe '#@include common-auth' $SSHD_PAM_CONF || sed -i 's/@include common-auth/#@include common-auth/' $SSHD_PAM_CONF
if [[ $ID == "rhel" || $ID=="alma" || $ID=="rocky" || $ID=="Centos" ]]
then
systemctl restart sshd
else
deb-systemd-invoke restart ssh.service
fi