#pragma once #include #include #include #include #include #include #include #include #include #include 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 { 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); } } template < typename Fun, typename... Ti > auto scan(Fun && f, const char * fmt, Ti... ti) const noexcept { char * response = nullptr; pam_prompt(pamh, PAM_PROMPT_ECHO_ON, &response, fmt, std::forward< Ti >(ti)...); if(response) { auto ret = f(response); free(response); return ret; } return std::result_of_t< Fun(char *) >(); } }; } // namespace rublon