#pragma once #include #include #include #include #include #include #include #include #include #include #include #include #include "utils.hpp" namespace rublon { class LinuxPam { pam_handle_t * pamh; 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) { rublon::log(rublon::LogLevel::Warning, "Cant read user from linux PAM"); ip = ""; } return ( const char * ) ip; } rublon::NonOwningPtr< const char > username() const { const char * user = NULL; pam_get_user(pamh, &user, nullptr); if(user == NULL) { rublon::log(rublon::LogLevel::Warning, "Cant read user from linux PAM"); user = ""; } return user; } template < typename... Ti > void print(const char * fmt, Ti... ti) const noexcept { pam_prompt(pamh, PAM_TEXT_INFO, nullptr, fmt, std::forward< Ti >(ti)...); } 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)...); if(responseBuffer) { auto ret = f(responseBuffer); free(responseBuffer); return std::optional{ret}; } return std::optional< std::result_of_t< Fun(char *) > >(); } }; } // namespace rublon