#include "auth.h" #include #include #include #include #include #include // crypt specified password std::string Auth::generate(const std::string& pw) { struct crypt_data data; memset((void *)&data, '\0', sizeof(data)); std::random_device rd; std::mt19937 rng{rd()}; std::uniform_int_distribution uid(0, 63); std::string chars{std::string(std::string::size_type(64), char('a'))}; std::iota(chars.begin() , chars.begin() + 26, 'a'); std::iota(chars.begin() + 26, chars.begin() + 52, 'A'); std::iota(chars.begin() + 52, chars.begin() + 62, '0'); chars[62] = '.'; chars[63] = '/'; std::string salt{{chars[uid(rng)], chars[uid(rng)]}}; char* result; if ((result = crypt_r(pw.data(), salt.data(), &data)) == nullptr) throw std::runtime_error("Error on crypt_r()"); return result; } // validate specified password against crypted hash bool Auth::validate(const std::string& crypted, const std::string& pw) { struct crypt_data data; memset((void *)&data, '\0', sizeof(data)); if (crypted.size() < 2) { std::cerr << "Warning: Bad password hash configured (size)" << std::endl; return false; } std::string salt{crypted.substr(0, 2)}; char* output; if ((output = crypt_r(pw.data(), salt.data(), &data)) == nullptr) { std::cerr << "Warning: Error on crypt_r()" << std::endl; return false; } return crypted == output; }